Auto-populated field in a Sequelize Model? - mysql

I'm creating a Model for a 'users' table in MySQL. Ideally I'd like to have a 'firstName' and 'lastName' field and a 'fullName' that would be the addition of the other 2.
Is it possible to have that programatically in the Model or do I have to take care of that at INSERT time ?
const User = sequelize.define("users", {
id: {
type: Sequelize.INTEGER,
autoIncrement: true,
allowNull: false,
primaryKey: true,
},
firstName: {
type: Sequelize.STRING(50),
allowNull: false,
},
lastName: {
type: Sequelize.STRING(50),
allowNull: false,
},
fullName: {
type: Sequelize.STRING(50),
allowNull: false,
// something that makes 'firstName' + ' ' + 'lastName' ❤️
},
email: {
type: Sequelize.INTEGER(30),
allowNull: false,
},
});

Virtual Colums are what you are looking for.
"Virtual" columns are columns that do not get saved in your database - they are calculated on the fly based on the values of other columns. They are helpful for saving space if there are values we want to use on our instances that can be easily calculated.
const User = sequelize.define("users", {
id: {
type: Sequelize.INTEGER,
autoIncrement: true,
allowNull: false,
primaryKey: true,
},
firstName: {
type: Sequelize.STRING(50),
allowNull: false,
},
lastName: {
type: Sequelize.STRING(50),
allowNull: false,
},
fullName: {
type: DataTypes.VIRTUAL,
get() {
return `${this.firstName} ${this.lastName}`;
}
},
email: {
type: Sequelize.INTEGER(30),
allowNull: false,
},
});
For more infromation see virtual fields.

Related

Sequelize select substring from a column as an alias

I'm trying to retrieve the first 4 characters of the school_name column and give the result the alias of schoolCode, but I'm receiving the following error:
original: RequestError: Invalid column name 'schoolCode'.
Currently I'm able to do it by using an aggregate function:
attributes: [
[Sequelize.fn('DISTINCT', Sequelize.col('STUDENT_ID')), 'studentId'],
'studentId',
'lastName',
'firstName',
'middleName',
[Sequelize.fn('SUBSTRING', Sequelize.col('SCHOOL_NAME'), 1, 4), 'schoolName'],
'courseNum',
'section'
],
I get the data that I need in an object with the property schoolName.
How can I get the same data in a property called schoolCode? when I change schoolName with schoolCode I get the above mentioned error
This is the definition of the table I'm querying
{
schoolName: {
type: DataTypes.STRING,
allowNull: true,
field: 'SCHOOL_NAME'
},
studentId: {
type: DataTypes.INTEGER,
allowNull: false,
field: 'STUDENT_ID',
},
lastName: {
type: DataTypes.STRING,
allowNull: true,
field: 'LAST_NAME'
},
firstName: {
type: DataTypes.STRING,
allowNull: true,
field: 'FIRST_NAME'
},
middleName: {
type: DataTypes.STRING,
allowNull: true,
field: 'MIDDLE_NAME'
},
programNum: {
type: DataTypes.STRING,
allowNull: true,
field: 'PROGRAM_NUM'
},
courseNum: {
type: DataTypes.STRING,
allowNull: true,
field: 'COURSE_NUM'
},
course: {
type: DataTypes.STRING,
allowNull: true,
field: 'COURSE'
},
section: {
type: DataTypes.STRING,
allowNull: true,
field: 'SECTION',
primaryKey: true
},
schStartDate: {
type: DataTypes.DATEONLY,
allowNull: true,
field: 'sch_start_date'
},
schEndDate: {
type: DataTypes.DATEONLY,
allowNull: true,
field: 'sch_end_date'
}
}

Sequelize: Insert failed to foreignKey column

I'm trying to insert data to my table with foreign keys from another table. The relationship is already successfully created. But when I try to insert data to the table, it always input null, and I already handle it with add allowNull: false. But still don't know how to input the value into the foreign key value inside table column.
This is my Product model:
{
id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
allowNull: false,
primaryKey: true
},
name: {
type: DataTypes.STRING,
allowNull: false
},
description: {
type: DataTypes.TEXT,
allowNull: true
},
price: {
type: DataTypes.DECIMAL,
allowNull: false,
validate: {
isNumeric: {
args: true,
msg: 'Wrong price format'
}
}
},
image: {
type: DataTypes.TEXT,
allowNull: false
}
},
{
sequelize,
paranoid: true,
modelName: 'product'
}
);
and this is my category model:
category.init(
{
id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
allowNull: false,
primaryKey: true
},
name: {
type: DataTypes.STRING,
allowNull: false
},
image: {
type: DataTypes.TEXT,
allowNull: false
}
},
{
sequelize,
paranoid: true,
modelName: 'category'
}
);
and this is relationship between them
category.hasMany(product, {
foreignKey: {
name: 'categoryId',
allowNull: false
},
onDelete: 'CASCADE'
});
product.belongsTo(category, {
foreignKey: {
name: 'categoryId',
allowNull: false
},
onDelete: 'CASCADE'
});
and on inserting code using express, this is the code:
const product = {
name,
description,
price,
image,
businessCompanyId,
categoryId
};
await Product.create(product);
Any help will be great, thank you!
Add a field of categoryId in Product model like this:-
categoryId: {
type: DataTypes.UUID,
allowNull: false,
references: {
model: "category",
key: "id"
}
},
I have not proper understanding of businessCompanyId but hope this will help you!

Trying to join parent / primary table to child / foreign table in sequelize

I'm trying to get all my articles data from articles table but also user data from users table i've made. I using sequelize to build database to MySQL database and also as a ORM, here's the snippet code
USER TABLE
const User = sequelize.define('users', ({
id: {
type: DataTypes.BIGINT,
primaryKey: true,
autoIncrement: true,
allowNull: false,
},
nama: {
type: DataTypes.STRING(50),
allowNull: false,
},
email: {
type: DataTypes.STRING(50),
allowNull: false,
},
password: {
type: DataTypes.STRING(50),
allowNull: false,
}
}))
ARTICLES CODE
const Articles = sequelize.define('articles', ({
id: {
type: DataTypes.BIGINT,
primaryKey: true,
autoIncrement: true,
allowNull: false,
},
title: {
type: DataTypes.STRING,
allowNull: false,
},
description: {
type: DataTypes.TEXT,
allowNull: false
},
gambar: {
type: DataTypes.STRING,
allowNull: false
},
userId: {
type: DataTypes.BIGINT,
allowNull: false,
}
}))
the relation
User.hasMany(Articles, {
onDelete: 'CASCADE',
onUpdate: 'CASCADE',
})
Articles.belongsTo(User, {
foreignKey: 'userId'
})
the ORM i've try
Articles.findAll({
include: [User]
})
it is always return that users table is not associated to artiles
You have to use as key word during creating relation ship.
Articles.belongsTo(User, {
as: 'user',
foreignKey: 'userId'
})
and then update form
Articles.findAll({include: [{
model: model.User,
as: 'user'
}]})

Could not find migration method: up

I am unable to migrate my models to MySQL db. It's throwing me the below error:
Loaded configuration file "config\config.json".
Using environment "development".
(node:5828) [SEQUELIZE0004] DeprecationWarning: A boolean value was passed to options.operatorsAliases. This is a no-op with v5 and should be removed.
== 20191218125700-mig_admin_roles: migrating =======
ERROR: Could not find migration method: up
models- admin_user.js
module.exports = (sequelize, DataTypes) => {
{
var admin_users = sequelize.define("adminUser", {
id: {
type: DataTypes.INTEGER(22),
allowNull: false,
primaryKey: true,
autoIncrement: true,
field: "id"
},
fname: {
type: DataTypes.STRING(20),
allowNull: false,
field: "fname"
},
lname: {
type: DataTypes.STRING(20),
allowNull: true,
field: "lname"
},
phoneNo: {
type: DataTypes.STRING(20),
allowNull: false,
field: "phoneNo"
},
emailId: {
type: DataTypes.STRING(20),
allowNull: false,
unique: true,
field: "emailId"
},
isActive: {
type: DataTypes.BOOLEAN,
allowNull: false,
defaultValue: "0",
field: "isActive"
},
password: {
type: DataTypes.STRING(128),
allownull: false,
field: "password"
}
});
admin_users.associate = models => {
admin_users.hasMany(models.adminRole, {
foreignKey: "roleId"
});
};
return admin_users;
}
};
migration: mig-admin_user.js
"use strict";
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.createTable("adminUser", {
id: {
type: Sequelize.INTEGER(22),
allowNull: false,
primaryKey: true,
autoIncrement: true,
field: "id"
},
fname: {
type: Sequelize.STRING(20),
allowNull: false,
field: "fname"
},
lname: {
type: Sequelize.STRING(20),
allowNull: true,
field: "lname"
},
phoneNo: {
type: Sequelize.STRING(20),
allowNull: false,
field: "phoneNo"
},
emailId: {
type: Sequelize.STRING(20),
allowNull: false,
unique: true,
field: "emailId"
},
isActive: {
type: Sequelize.BOOLEAN,
allowNull: false,
defaultValue: "0",
field: "isActive"
},
password: {
type: Sequelize.STRING(128),
allownull: false,
field: "password"
}
});
},
down: (queryInterface, Sequelize) => {
/*
Add reverting commands here.
Return a promise to correctly handle asynchronicity.
Example:
return queryInterface.dropTable('users');
*/
}
};
I tried looking for this particular error, but couldn't find anything.
could anyone please tell where i might be going wrong?
You need a .sequelizerc in the root of your project and it contains something like this :
module.exports = {
'config': 'database/config.js',
'migrations-path': 'database/migrations',
'seeders-path': 'database/seeders'
}
And you have to point where are your migrations been located.

How to define unique index on multiple columns in sequelize

How do I define a unique index on a combination of columns in sequelize. For example I want to add a unique index on user_id, count and name.
var Tag = sequelize.define('Tag', {
id: {
type: DataTypes.INTEGER(11),
allowNull: false,
primaryKey: true,
autoIncrement: true
},
user_id: {
type: DataTypes.INTEGER(11),
allowNull: false,
},
count: {
type: DataTypes.INTEGER(11),
allowNull: true
},
name: {
type: DataTypes.STRING,
allowNull: true,
})
You can refer to this doc http://docs.sequelizejs.com/en/latest/docs/models-definition/#indexes
You will need to change your definition like shown below and call sync
var Tag = sequelize.define('Tag', {
id: {
type: DataTypes.INTEGER(11),
allowNull: false,
primaryKey: true,
autoIncrement: true
},
user_id: {
type: DataTypes.INTEGER(11),
allowNull: false,
},
count: {
type: DataTypes.INTEGER(11),
allowNull: true
},
name: {
type: DataTypes.STRING,
allowNull: true,
}
},
{
indexes: [
{
unique: true,
fields: ['user_id', 'count', 'name']
}
]
});
I have same issue to applied composite unique constraint to multiple
columns but nothing work with Mysql, Sequelize(4.10.2) and NodeJs
8.9.4 finally I fixed through following code.
queryInterface.createTable('actions', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
},
system_id: {
type: Sequelize.STRING,
unique: 'actions_unique',
},
rule_id: {
type: Sequelize.STRING,
unique: 'actions_unique',
},
plan_id: {
type: Sequelize.INTEGER,
unique: 'actions_unique',
}
}, {
uniqueKeys: {
actions_unique: {
fields: ['system_id', 'rule_id', 'plan_id']
}
}
});
If the accepted one is not working then try the below code. It worked for me in my case rather the accepted one.
var Tag = sequelize.define('Tag', {
id: {
type: DataTypes.INTEGER(11),
allowNull: false,
primaryKey: true,
autoIncrement: true
},
user_id: {
type: DataTypes.INTEGER(11),
allowNull: false,
unique: 'uniqueTag',
},
count: {
type: DataTypes.INTEGER(11),
allowNull: true,
unique: 'uniqueTag',
},
name: {
type: DataTypes.STRING,
allowNull: true,
unique: 'uniqueTag',
}
});
I tried to create an index on a single column.
This worked for me. Hope this helps.
Model
module.exports = (sequelize, DataTypes) => {
const Tag = sequelize.define(
"Tag",
{
name: { type: DataTypes.STRING, unique: true },
nVideos: DataTypes.INTEGER
},
{
indexes: [
{
unique: true,
fields: ["name"]
}
]
}
);
return Tag;
};
Migration
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.createTable(
"Tags",
{
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
name: {
type: Sequelize.STRING,
unique: "unique_tag"
},
nVideos: { type: Sequelize.INTEGER },
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
},
{
uniqueKeys: {
unique_tag: {
customIndex: true,
fields: ["name"]
}
}
}
);
},
down: queryInterface => {
return queryInterface.dropTable("Tags");
}
};
I prefer sequelize sync method with composite unique, If not passing indexes name u will get a error as below on adding many indexes in index array.
error: SequelizeDatabaseError: Identifier name 'LONG_NAME' is too long
module.exports = function (sequelize: any, DataTypes: any) {
return sequelize.define('muln_user_goals_transaction', {
id: {
type: DataTypes.INTEGER(11),
allowNull: false,
autoIncrement: true,
primaryKey: true,
},
name: {
type: DataTypes.STRING(),
allowNull: false,
},
email: {
type: DataTypes.STRING(),
allowNull: false,
},
phone: {
type: DataTypes.STRING(),
allowNull: false,
},
amount: {
type: DataTypes.INTEGER(8),
allowNull: false
},
deleted: {
type: DataTypes.BOOLEAN,
defaultValue: false,
},
}, {
tableName: 'muln_user_goals_transaction',
timestamps: false,
indexes: [
{
name: 'unique_index',
unique: true,
fields: ['name', 'email', 'phone', 'amount', 'deleted']
}
],
defaultScope: {
where: {
deleted: false
}
}
});
};
Sequelize composite unique (manual)
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.createTable('Model', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
fieldOne: {
type: Sequelize.INTEGER,
unique: 'uniqueTag',
allowNull: false,
references: {
model: 'Model1',
key: 'id'
},
onUpdate: 'cascade',
onDelete: 'cascade'
},
fieldsTwo: {
type: Sequelize.INTEGER,
unique: 'uniqueTag',
allowNull: false,
references: {
model: 'Model2',
key: 'id'
},
onUpdate: 'cascade',
onDelete: 'cascade'
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
})
.then(function() {
return queryInterface.sequelize.query(
'ALTER TABLE `UserFriends` ADD UNIQUE `unique_index`(`fieldOne`, `fieldTwo`)'
);
});
},
down: (queryInterface, Sequelize) => {
return queryInterface.dropTable('Model');
}
};