sequelize with postgres database not working after migration from mysql - mysql

I change MySQL databese into postgreSQL in sequelize. But After migration I have issue with upper and lowercase first letter in Table or Model...
Before my MySQL version was working properly but after migration I got error message:
500 SequelizeDatabaseError: relation "Users" does not exist
My User model:
module.exports = function(sequelize, Sequelize) {
var User = sequelize.define("User", {
// profile
userlevel: Sequelize.STRING,
restaurant: Sequelize.STRING,
access: Sequelize.STRING,
optionsid: Sequelize.STRING,
email: Sequelize.STRING,
name: Sequelize.STRING,
gender: Sequelize.STRING,
location: Sequelize.STRING,
website: Sequelize.STRING,
picture: Sequelize.STRING,
// Oauth
password: {
type: Sequelize.STRING,
set: function(v) {
var salt = bcrypt.genSaltSync(5);
var password = bcrypt.hashSync(v, salt);
return this.setDataValue('password', password);
}
},
.....
Migration file:
"use strict";
module.exports = {
up: function(migration, DataTypes, done) {
migration.createTable("users", {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: DataTypes.INTEGER
},
userlevel: {
type: DataTypes.STRING,
defaultValue: '5'
},
restaurant: {
type: DataTypes.STRING,
defaultValue: ''
},
access: {
type: DataTypes.STRING,
defaultValue: '1'
},
optionsid: {
type: DataTypes.STRING,
defaultValue: ''
},
email: {
type: DataTypes.STRING,
allowNull: false
},
name: {
type: DataTypes.STRING,
defaultValue: ''
},
gender: {
type: DataTypes.STRING,
defaultValue: ''
},
location: {
type: DataTypes.STRING,
defaultValue: ''
},
website: {
type: DataTypes.STRING,
defaultValue: ''
},
picture: {
type: DataTypes.STRING,
defaultValue: ''
},
password: {
type: DataTypes.STRING
},
facebook: {
type: DataTypes.STRING
},
twitter: {
type: DataTypes.STRING
},
google: {
type: DataTypes.STRING
},
tokens: {
type: DataTypes.STRING
},
resetPasswordToken: {
type: DataTypes.STRING
},
resetPasswordExpires: {
type: DataTypes.DATE
},
createdAt: {
allowNull: false,
type: DataTypes.DATE
},
updatedAt: {
allowNull: false,
type: DataTypes.DATE
}
}).done(done);
},
down: function(migration, DataTypes, done) {
migration.dropTable("users").done(done);
}
};
If I change first letter of table in postgreSQL to uppercase everything is working properly...

PostgreSQL folds the names of ordinary identifiers to lower case. So users, Users, and USERS all resolve to the identifier users.
Delimited identifiers are different. (Delimited identifiers are surrounded by double quotes.) The identifiers "users", "Users", and "USERS" are three different identifiers.
Your migration created the table "users". Sequelize is looking for the table "Users". (Delimited identifiers--two different tables.)
You should probably change the identifier in your migration to "Users". There are other ways, but this is the path of least resistance. If this is already in production, you might be better off writing another migration that renames "users" to "Users".

Related

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 generate a migration after generating the models using sequelize-auto

I have run this command to generate the models from my MySQL:
node node_modules/sequelize-auto/bin/sequelize-auto -h localhost -d coasteye_new -u root -x PASSWORD --dialect mysql -o models
So the models are now stored in the "node_project/models" directory. For example this one:
const Sequelize = require('sequelize');
module.exports = function(sequelize, DataTypes) {
return sequelize.define('user', {
id: {
autoIncrement: true,
type: DataTypes.INTEGER,
allowNull: false,
primaryKey: true
},
name: {
type: DataTypes.STRING(100),
allowNull: true,
unique: "name"
},
password: {
type: DataTypes.STRING(100),
allowNull: false
},
id_role: {
type: DataTypes.INTEGER,
allowNull: false
},
role: {
type: DataTypes.ENUM('root','twm staff','client'),
allowNull: false
},
email: {
type: DataTypes.STRING(70),
allowNull: false,
unique: "unique_email"
},
fullname: {
type: DataTypes.STRING(100),
allowNull: true
},
activated: {
type: DataTypes.TINYINT,
allowNull: false,
defaultValue: 1
},
token: {
type: DataTypes.STRING(100),
allowNull: false
},
phone: {
type: DataTypes.STRING(70),
allowNull: false
},
api_token: {
type: DataTypes.STRING(200),
allowNull: true
},
api_token_valid_until: {
type: DataTypes.DATE,
allowNull: true
},
has_stations_in_the_new_user_deployment_xref_table: {
type: DataTypes.TINYINT,
allowNull: false,
defaultValue: 0
},
send_the_status_daily_report_by_email: {
type: DataTypes.TINYINT,
allowNull: false,
defaultValue: 0
}
}, {
sequelize,
tableName: 'user',
timestamps: false,
indexes: [
{
name: "PRIMARY",
unique: true,
using: "BTREE",
fields: [
{ name: "id" },
]
},
{
name: "unique_email",
unique: true,
using: "BTREE",
fields: [
{ name: "email" },
]
},
{
name: "name",
unique: true,
using: "BTREE",
fields: [
{ name: "name" },
]
},
]
});
};
After that I have modified the field "phone" by "telephone" this way:
phone: {
type: DataTypes.STRING(70),
allowNull: false
},
to
telephone: {
type: DataTypes.STRING(70),
allowNull: false
},
Then I have run this:
(env) jgarcia#Javier-PC:/var/www/node_test$ npx sequelize
migration:generate --name test_migration
Sequelize CLI [Node: 18.3.0, CLI: 6.4.1, ORM: 6.20.1]
migrations folder at "/var/www/node_test/migrations" already exists.
New migration was created at
/var/www/node_test/migrations/20220615115322-test_migration.js .
But I get an "empty" migration as you can see here below:
(env) jgarcia#Javier-PC:/var/www/node_test$ cat /var/www/node_test/migrations/20220615115322-test_migration.js
'use strict';
module.exports = {
async up (queryInterface, Sequelize) {
/**
* Add altering commands here.
*
* Example:
* await queryInterface.createTable('users', { id: Sequelize.INTEGER });
*/
},
async down (queryInterface, Sequelize) {
/**
* Add reverting commands here.
*
* Example:
* await queryInterface.dropTable('users');
*/
}
};
I expected that the file 20220615115322-test_migration.js contained some reference to my change: from phone to telephone.
Regards
Javier
This is what the migration:generate CLI command does. It doesn't interact with your models at all. See this SO thread for additional information.
You can pass additional parameters into your migration:generate command to get the CLI to write some of the code for you. You can also use Sequelize Auto-Migrations, but that package has not seen any updates in a long time and probably has compatibility issues with newer versions of Sequelize.

ERROR: Cannot add foreign key constraint-

I wrote a nodejs app with mysql db and Sequalize as an ORM. Every things is ok. I define models and migration to create database and seeders. I want to create a product model that in this model i have two foreign keys: (categoryId & shopId).
when i was create migration files, I create shop model after product model. and this is create a problem for me. when i want to create table in database using "sequelize db:migrate" command i get this error:
ERROR: Cannot add foreign key constraint
I read this link and know this is not the reason for my problem.
but how can i resolve this bug? i try to define up and down as an async function but this error did not resolve.
module.exports = {
up: (queryInterface, Sequelize) => queryInterface.createTable(
'products', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER,
},
name: {
type: Sequelize.STRING(255),
allowNull: false,
},
description: {
type: Sequelize.STRING(1024),
allowNull: false,
},
price: {
type: Sequelize.FLOAT,
allowNull: false,
},
old_price: {
type: Sequelize.FLOAT,
allowNull: false,
},
type: {
type: Sequelize.STRING(255),
},
height: {
type: Sequelize.INTEGER,
},
width: {
type: Sequelize.INTEGER,
},
categoryId: {
type: Sequelize.INTEGER,
references: {
model: 'categories',
key: 'id',
},
},
shopId: {
type: Sequelize.INTEGER,
references: {
model: 'shops',
key: 'id',
},
},
createdAt: {
allowNull: false,
type: Sequelize.DATE,
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE,
},
},
),
down: (queryInterface, Sequelize) => queryInterface.dropTable('products'),
}
You're passing the model as string. You need to point to your class.
Try this:
categoryId: {
type: Sequelize.INTEGER,
references: {
model: categories,
key: 'id',
},
},

Auto-populated field in a Sequelize Model?

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.

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.