Sequelize Seeding ARRAY(ENUM) - javascript

I cannot seem to figure out how to seed ARRAY(ENUM) using Sequelize. When I am registering a user via my app, I can create a new user fine, but when I am using the queryInterface.bulkInsert in a seed file, I am getting:
ERROR: column "roles" is of type "enum_Users_roles"[] but expression is of type text[]
here is my code:
return queryInterface.bulkInsert('Users', [
{
email: faker.internet.email(),
roles: ['user'],
password: "hash",
public_id: faker.random.uuid(),
created_at: new Date(),
updated_at: new Date()
}
]);
and here is my migration file for the user:
return queryInterface.createTable('Users', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
email: {
type: Sequelize.STRING,
allowNull: false
},
password: {
type: Sequelize.STRING,
allowNull: false
},
roles: {
type: Sequelize.ARRAY(Sequelize.ENUM({
values: ['user', 'setter', 'admin']
})),
allowNull: false
},
public_id: {
type: Sequelize.UUID,
defaultValue: Sequelize.UUIDV4,
allowNull: false
},
created_at: {
allowNull: false,
type: Sequelize.DATE
},
updated_at: {
allowNull: false,
type: Sequelize.DATE
}
})
I am just assuming that I am doing it wrong, but I cannot find any documentation on how to do it correctly. If anyone can help and explain (teach a man to fish), I would appreciate it.

Someone answered on github here
This is their answer which worked for me (and I greatly appreciate)
You can use this code
class Item extends Sequelize.Model { }
Item.init({
name: { type: DataTypes.STRING },
values: {
type: DataTypes.ARRAY(DataTypes.ENUM({
values: ['a', 'b']
}))
}
}, {
sequelize,
timestamps: true
})
sequelize.sync({ force: true }).then(async () => {
await sequelize.queryInterface.bulkInsert('Items', [
{
name: 'xyz',
values: sequelize.literal(`ARRAY['a']::"enum_Items_values"[]`),
createdAt: new Date(),
updatedAt: new Date()
}
]);
});
Executing (default): INSERT INTO "Items" ("name","values","createdAt","updatedAt") VAL
[1]: https://github.com/sequelize/sequelize/issues/11541#issuecomment-542791562
Obviously you'll want to change the array values and enum values. For example, mine would be
ARRAY['user']::"enum_Users_values"[]

Related

How create (optimize) service on Backend (ExpressJS) with sequelize

Tried to create API for internet store using ExpressJS and sequelize. I have users, basket and devices. To connect basket and choosen by user devices used middle table BasketDevice.
Models:
export const Models = {
User: sequelize.define('user',
{
id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
email: { type: DataTypes.STRING, unique: true },
password: { type: DataTypes.STRING },
role: { type: DataTypes.STRING, defaultValue: 'USER' },
isActivated: { type: DataTypes.BOOLEAN, defaultValue: false},
activationLink: { type: DataTypes.STRING, unique: true }
}
),
Basket: sequelize.define('basket',
{
id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
}
),
BasketDevice: sequelize.define('basketDevice',
{
id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
}
),
Device: sequelize.define('device',
{
id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
name: { type: DataTypes.STRING, allowNull: false, unique: true },
price: { type: DataTypes.INTEGER, allowNull: false },
img: { type: DataTypes.STRING, allowNull: false },
rating: { type: DataTypes.INTEGER, defaultValue: 0 },
}
}
Assotiations between tables:
Models.User.hasOne(Models.Basket)
Models.Basket.belongsTo(Models.User)
Models.Basket.hasMany(Models.BasketDevice, {as: 'devices'})
Models.BasketDevice.belongsTo(Models.Basket)
Models.Device.hasMany(Models.BasketDevice)
Models.BasketDevice.belongsTo(Models.Device)
Tryed to give in response basket include basket device
Basket service:
class BasketService {
async getBasket(token: string) {
const userData = await TokenService.verifyRefreshToken(token) as any
const basket = await Models.Basket.findOne({
where: { userId: userData.id },
include: [{model: Models.BasketDevice, as: 'devices'}]
})
return basket
}
}
Don't know how create getBasket function that gives added to cart devices and counting of one device
What is the opltimal way to give devices added in basket?

How to use sequelize beforeCreate to autogenerate Id value?

I am tryiong to generate a BINARY(16) value for a model that Id.
I used the defaultValue parameter but ended up getting
duplicate key errors in mysql
.
So i found If I use beforeCreate then it would be uniqe every time but when Im doing the actual create im getting
Id can not be null errors
my model:
const utility = require('utils/utilities');
module.exports = function(sequelize, DataTypes) {
const weddings = sequelize.define(
'weddings', {
Id: {
primaryKey: true,
allowNull: false,
type: 'BINARY(16)',
},
Name: {
type: DataTypes.STRING(150),
allowNull: false,
comment: 'null',
},
HouseId: {
type: DataTypes.INTEGER(11),
allowNull: false,
comment: 'null',
references: {
model: 'house',
key: 'Id',
},
},
WDate: {
type: DataTypes.DATE,
allowNull: false,
comment: 'null',
},
Active: {
type: DataTypes.BOOLEAN,
allowNull: false,
comment: 'null',
},
},
{
hooks: {
beforeCreate() {
const generateValue = Buffer.from(utility.generateUID().replace('-', ''), 'hex');
weddings.Id = generateValue;
}
}
}, {
tableName: 'weddings',
}
);
return weddings;
};
error:
weddings.Id cannot be null
What am I missing?
You can use instance hook like this:
const utility = require('utils/utilities');
module.exports = function(sequelize, DataTypes) {
const weddings = sequelize.define(
'weddings', {
Id: {
primaryKey: true,
allowNull: false,
type: 'BINARY(16)',
},
Name: {
type: DataTypes.STRING(150),
allowNull: false,
comment: 'null',
},
HouseId: {
type: DataTypes.INTEGER(11),
allowNull: false,
comment: 'null',
references: {
model: 'house',
key: 'Id',
},
},
WDate: {
type: DataTypes.DATE,
allowNull: false,
comment: 'null',
},
Active: {
type: DataTypes.BOOLEAN,
allowNull: false,
comment: 'null',
},
},
{
}, {
tableName: 'weddings',
}
);
weddings.beforeCreate(async (data, options) => {
data.Id = await Buffer.from(utility.generateUID().replace('-', ''), 'hex');
});
return weddings;
};
If you want to emit hooks for each individual record, along with the bulk hooks you can pass individualHooks: true to the call.
table.update( req.body, {
where: where,
returning: true,
individualHooks: true
plain: true
})
create:
db.weddings.create({
...args,
}),
for other information you can read it at:
https://sequelize.org/v5/manual/hooks.html

Sequelize constraint on delete

I would like to add a constraint inside my migration file, for example when I try and delete a row and there's another row inside another table that's referencing the row i'm deleting it needs to throw an error. There will also be multiple tables that will associate with the table.
return queryInterface.createTable('status', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
name: {
type: Sequelize.STRING,
unique: true
},
slug: {
type: Sequelize.STRING,
unique: true
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
},
});
table status:
...
id
table locales:
...
id_status
table users
...
id_status
id_status: {
type: Sequelize.INTEGER,
references: {
model: 'status',
key: 'id',
onDelete: 'restrict'
}
},
id_status: {
type: Sequelize.INTEGER,
references: {
model: 'status',
key: 'id',
},
onDelete: 'restrict'
},

Sequelize migration error: Cannot read property 'length' of undefined

This is the tutorial I followed: https://medium.com/#prajramesh93/getting-started-with-node-express-and-mysql-using-sequelize-ed1225afc3e0
This is node js project using express + mysql where I use and ORM Sequelize.
I get this error when trying to run sequelize db:migrate
'use strict';
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.createTable('Employees', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
name: {
type: Sequelize.STRING
},
designation: {
type: Sequelize.STRING
},
salary: {
type: Sequelize.NUMBER
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
},
companyId: {
type: Sequelize.NUMBER,
onDelete: 'CASCADE',
references: {
model: 'Companies',
key: 'id',
as: 'companyId',
}
}
});
},
down: (queryInterface, Sequelize) => {
return queryInterface.dropTable('Employees');
}
};
Problem was relying on NUMBER DataType. Which was not found in the list of DataTypes of Sequelize ( https://sequelize.org/master/manual/model-basics.html#data-types )
Change the following:
salary: {
type: Sequelize.NUMBER
}
to:
salary: {
type: Sequelize.DECIMAL(10, 2)
}
Also remember to update DataType the model related.

Sequelize request error SequelizeEagerLoadingError

I’m new with sequelize I’m trying to make a request with associate tables
I have a first model called Experience
module.exports = function (sequelize, DataTypes) {
const Experience = sequelize.define('experience', {
internalId: {
type: DataTypes.BIGINT,
unique: true,
allowNull: false,
},
label: {
type: DataTypes.STRING,
unique: false,
allowNull: false,
},
picture: {
type: DataTypes.TEXT,
unique: false,
allowNull: true,
},
type: {
type: DataTypes.STRING,
validate: {
isIn: {
args: [[
'generic',
'specific',
]],
msg: 'Must be a valid type',
},
},
unique: false,
allowNull: true,
},
author: {
type: DataTypes.STRING,
unique: false,
allowNull: true,
defaultValue: 'import',
},
isActive: {
type: DataTypes.BOOLEAN,
defaultValue: true,
},
});
Experience.associate = (models) => {
Experience.belongsToMany(models.Tag, {
as: 'Tags',
through: models.ExperienceTag,
});
};
return Experience;
};
a second called Tags
module.exports = function (sequelize, DataTypes) {
const Tag = sequelize.define('tag', {
internalId: {
type: DataTypes.STRING,
unique: true,
allowNull: false,
},
name: {
type: DataTypes.STRING,
unique: false,
allowNull: false,
},
author: {
type: DataTypes.STRING,
unique: false,
allowNull: true,
defaultValue: 'import',
},
isActive: {
type: DataTypes.BOOLEAN,
defaultValue: true,
},
});
Tag.associate = (models) => {
Tag.belongsToMany(models.Experience, {
as: 'Experiences',
through: models.ExperienceTag,
});
};
return Tag;
};
The association table name was ExperienceTags
I would like get all the Experiencewho have a tagId = 44
This is my request:
Experience.findAll({
include: [{
model: ExperienceTag,
where: { tagId: 44 },
}],
})
.then((results) => {
winston.warn(JSON.stringify(results, null, 2));
res.status(200)
.send(results);
})
.catch(error => res.status(500)
.send({ error: error.toString() }));
But when I execute it I have an error like:
{
"error": "SequelizeEagerLoadingError: experienceTag is not associated to experience!"
}
I think you like to include Tag rather than ExperienceTag, the following example may help you
Experience.findAll({
include: [{
model: Tag, //model name which you want to include
as: 'Tags', // you have to pass alias as you used while defining
where: { tagId: 44 },
}],
})
I think , you need to add as: 'Experiences' , in your include as you have defined association with alias
Change this
Experience.findAll({
include: [{
model: ExperienceTag,
where: { tagId: 44 },
}],
})
With
Experience.findAll({
include: [{
model: ExperienceTag,
as: 'Experiences', // <---- HERE
where: { tagId: 44 },
}],
})

Categories