Sequelize query singular instead of plural table name - node.js

I have an problem and I can't find anything that can solve it. I'm using sequelize and graphql to create an API in nodeJS. The database is using PostgresQL.
So I have two models: Simulation and Data. They are in two tables Simulations and Datas. The relation between them is one Simulation to many Datas.
The problem is this: when I make a query with Simulation (ex: Simulation.findAll()), it works correctly, querying "Simulations", but with Data, it queries on the "Data" table, not "Datas". What I really don't understand is that the code of my two models are almost the same.
Here is the model for Simulation:
module.exports = (sequelize, DataTypes) => {
const Simulation = sequelize.define('Simulation', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: DataTypes.INTEGER,
},
name: {
type: DataTypes.STRING,
allowNull: false,
},
});
Simulation.associate = function(models) {
Simulation.hasMany(models.Data, {
foreignKey: 'SimulationId',
})
};
return Simulation;
};
Here is the model for Data:
module.exports = (sequelize, DataTypes) => {
const Data = sequelize.define('Data', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: DataTypes.INTEGER,
},
name: {
type: DataTypes.STRING,
allowNull: false
},
content: {
type: DataTypes.TEXT,
allowNull: false
},
SimulationId: {
allowNull: false,
type: DataTypes.INTEGER,
},
});
Data.associate = function(models) {
Data.belongsTo(models.Simulation, {
foreignKey: 'SimulationId',
targetKey: 'id',
allowNull: false,
onDelete: 'CASCADE'
});
};
return Data;
};
And here are the migration files:
Simulation
'use strict';
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.createTable('Simulations', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
name: {
type: Sequelize.STRING,
allowNull: false,
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
});
},
down: (queryInterface, Sequelize) => {
return queryInterface.dropTable('Simulations');
}
};
Data
'use strict';
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.createTable('Datas', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
name: {
type: Sequelize.STRING,
allowNull: false
},
content: {
type: Sequelize.TEXT,
allowNull: false
},
SimulationId: {
allowNull: false,
type: Sequelize.INTEGER,
onDelete: 'CASCADE',
references: {
model: 'Simulation',
key: 'id',
as: 'SimulationId',
},
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
});
},
down: (queryInterface, Sequelize) => {
return queryInterface.dropTable('Datas');
}
};
Thanks for helping me :)

You can use freezeTableName option to set whatever the model name you want, sequelize will not make the model names plural.

Sequelize automatically makes the model names plural. Why not call the table "Data" It is actually a plural form of the word "Data", so maybe a better name for the table.

Related

Sequelize addConstraint syntax

Im trying to add two tables, Playlist and Label.
Label optionally has a playlist, many playlists can relate to the same label.
In order to add the foreign key constraint to playlist im trying to add it using addConstraint.
The docs are terrible on this .
This is what i have:
"use strict";
module.exports = {
up: async (queryInterface, Sequelize) => {
await queryInterface.createTable("Playlist", {
id: { type: Sequelize.STRING, primaryKey: true, allowNull: false },
track_uri: Sequelize.STRING,
track: Sequelize.STRING(150),
artist: Sequelize.STRING(150),
added_at: {
type: Sequelize.DATE,
defaultValue: new Date(),
allowNull: false,
},
created_at: {
type: Sequelize.DATE,
defaultValue: new Date(),
allowNull: false,
},
is_album_track: Sequelize.BOOLEAN,
label: { type: Sequelize.STRING, unique: true },
});
await queryInterface.createTable("Label", {
id: { type: Sequelize.STRING, primaryKey: true },
playlist_link: {
type: Sequelize.STRING(150),
unique: true,
allowNull: false,
},
password: { type: Sequelize.STRING, allowNull: false },
email: { type: Sequelize.STRING, allowNull: false },
playlist: {
type: Sequelize.STRING,
foreignKey: true,
references: {
model: "Playlist",
label: "id",
},
},
});
await queryInterface.addConstraint("Playlist", {
type: "foreign key",
fields: ["label"],
name: "label_fkey",
references: {
table: "Label",
field: "id",
},
onDelete: "cascade",
onUpdate: "cascade",
});
},
down: async (queryInterface, Sequelize) => {
await queryInterface.dropTable("Label");
await queryInterface.dropTable("Playlist");
},
};
Im getting this error:
ERROR: column "label" referenced in foreign key constraint does not exist

Cannot read property 'menu_id' of undefined

I tried to create database with 3 tables: restaurant,restaurant_menu,menu and their relationship is restaurant have many menu and menu can belong to many restarant by sequelize in Nodejs.
restaurant.model.js
'use strict';
module.exports = (sequelize, DataTypes) => {
const restaurant = sequelize.define('restaurant', {
id: {
type: DataTypes.INTEGER,
allowNull: false,
autoIncrement: true,
primaryKey: true
},
name: DataTypes.STRING,
address: DataTypes.STRING,
phone: DataTypes.STRING,
lat: {
type: DataTypes.DOUBLE,
allowNull: false,
defaultValue: 0
},
lng: {
type: DataTypes.DOUBLE,
allowNull: false,
defaultValue: 0
},
user_owner: {
type: DataTypes.INTEGER,
defaultValue: 0
},
image: {
type: DataTypes.TEXT,
allowNull: false
},
payment_url: {
type: DataTypes.TEXT,
allowNull: false
}
}, {
freezeTableName: true,
timestamps: false
});
restaurant.associate = function (models) {
// associations can be defined here
restaurant.belongsToMany(models.menu, {
through: {
model: models.restaurant_menu
},
foreignKey: 'restaurant_id'
})
};
return restaurant;
};
menu.model.js
'use strict';
module.exports = (sequelize, DataTypes) => {
const menu = sequelize.define('menu', {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
allowNull: false
},
name: DataTypes.STRING(50),
description: DataTypes.STRING(500),
image: DataTypes.TEXT
}, {
freezeTableName: true,
timestamps: false
});
menu.associate = function (models) {
// associations can be defined here
menu.belongsToMany(models.restaurant, {
through: {
model: models.restaurant_menu
},
foreignKey: "menu_id"
});
};
return menu;
};
restaurant_menu.model.js
'use strict';
module.exports = (sequelize, DataTypes) => {
const restarant_menu = sequelize.define('restarant_menu', {
restaurant_id: {
type: DataTypes.INTEGER,
primaryKey: true,
allowNull: false,
references: {
model: 'restaurant'
}
},
menu_id: {
type: DataTypes.INTEGER,
primaryKey: true,
allowNull: false,
references: {
model: 'menu'
}
}
}, {
freezeTableName: true,
timestamps: false
});
restarant_menu.associate = function (models) {
// associations can be defined here
};
return restarant_menu;
};
i tried to run migration, but i get error:
Cannot read property 'menu_id' of undefined
How can I fix it?
I believe you are writing old syntax, checkout documentation.
https://sequelize.org/master/manual/advanced-many-to-many.html

Sequelize foreign key with association

I have a database that was created with Postgres that was set up for a single foreign key association, Now, this would be mapped as a role table model
consider I have two tables user and roles
roles contain role details and user contain user details of role
const uuid = require('uuid/v4');
('use strict');
module.exports = (sequelize, DataTypes) => {
const role = sequelize.define(
'role',
{
id: {
allowNull: false,
primaryKey: true,
type: DataTypes.UUID,
},
name: {
type: DataTypes.STRING,
allowNull: false,
},
},
{}
);
role.beforeCreate((role) => (role.id = uuid()));
role.associate = function (models) {
role.hasMany(models.user), { foreignKey: 'roleId', as: 'user_roleId' };
};
return role;
};
role migration
'use strict';
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.createTable('roles', {
id: {
allowNull: false,
primaryKey: true,
type: Sequelize.UUID,
},
name: {
type: Sequelize.STRING,
},
createdAt: {
allowNull: false,
type: Sequelize.DATE,
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE,
},
});
},
down: (queryInterface, Sequelize) => {
return queryInterface.dropTable('roles');
},
};
user model
const uuid = require('uuid/v4');
('use strict');
module.exports = (sequelize, DataTypes) => {
const user = sequelize.define(
'user',
{
id: {
allowNull: false,
primaryKey: true,
type: DataTypes.UUID,
},
firstName: {
type: DataTypes.STRING,
allowNull: false,
},
lastName: DataTypes.STRING,
email: {
type: DataTypes.STRING,
allowNull: false,
},
password: {
type: DataTypes.STRING,
allowNull: false,
},
phoneNumber: {
type: DataTypes.STRING,
},
roleId: {
type: DataTypes.UUID,
},
},
{
timestamps: true,
paranoid: true,
defaultScope: {
attributes: { exclude: ['password'] },
},
}
);
user.beforeCreate((user) => (user.id = uuid()));
user.associate = function (models) {
user.belongsTo(models.role, { foreignKey: 'roleId', onDelete: 'CASCADE' });
};
return user;
};
user migration
'use strict';
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.createTable('users', {
id: {
allowNull: false,
primaryKey: true,
type: Sequelize.UUID,
},
firstName: {
type: Sequelize.STRING,
},
lastName: {
type: Sequelize.STRING,
},
email: {
type: Sequelize.STRING,
},
password: {
type: Sequelize.STRING,
},
phoneNumber: {
type: Sequelize.STRING,
},
roleId: {
type: Sequelize.UUID,
},
createdAt: {
allowNull: false,
type: Sequelize.DATE,
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE,
},
deletedAt: {
allowNull: true,
type: Sequelize.DATE,
},
});
},
down: (queryInterface, Sequelize) => {
return queryInterface.dropTable('users');
},
};
after running the migration these tables are created in my database.role_id is also present in the user table. but role_id is not generated as a foreign key in my user table. also please verify that the relationship which is mention here(one to many) is correct or not.
please verify my code and give me any suggestions if any changes required. I'm new in development
Your user migration also needs to know about the foreign key; you do this by adding a references: key to the column definition. The Sequelize documentation has a foreign key example; scroll about half way down the page (or just search for references).
In your case the user migration should look something like:
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.createTable('users', {
// ... other fields omitted
roleId: {
type: Sequelize.UUID,
references: {
model: { tableName: 'role' }
key: 'id',
},
},
// ... more fields omitted
});
},
// down: omitted
}

Sequelize duplicate key value violates unique constraint

I am working on nodeJs, and postgresql.
I am facing with an error
duplicate key value violates unique constraint \"AuthoriseDates_pkey\"
Key (id)=(371) already exists.
I set the column id is autoIncrement: true, don't understand why this happens
the max id of columns is 647 but now I cannot insert a record in this table.
here is migrate code :
module.exports = {
up(queryInterface, Sequelize) {
return queryInterface.createTable('AuthoriseDates', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER,
},
userId: {
type: Sequelize.INTEGER,
references: { model: 'Users', key: 'id' },
},
lastAuthorise: {
type: Sequelize.DATE,
},
createdAt: {
allowNull: false,
type: Sequelize.DATE,
defaultValue: Sequelize.fn('NOW'),
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE,
defaultValue: Sequelize.fn('NOW'),
},
});
},
down(queryInterface) {
return queryInterface.dropTable('AuthoriseDates');
},
};
here is models:
module.exports = (sequelize, DataTypes) => {
const authoriseDate = sequelize.define('AuthoriseDate', {
id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
userId: DataTypes.INTEGER,
lastAuthorise: DataTypes.DATE,
});
authoriseDate.associate = (models) => {
// associations can be defined here
authoriseDate.belongsTo(models.User, { foreignKey: 'userId', });
};
return authoriseDate;
};
here is code insert:
models.AuthoriseDate.create({
userId: userId,
lastAuthorise: new Date().toISOString(),
}).then((create) => {}).catch((error) => {
loggerServer.err('error ', error);
loggerServer.log('debug', { error: error });
return res.status(500).json(result);
});

Sequelize.js still deletes table row even if paranoid is set to true

I'm having trouble getting Sequelize.js to soft delete the rows in my table. I used Sequelize cli to do all my migrations and I'm not using the sync feature to resync the database on start. I have the timestamp fields and even the deletedAt field in my migration and models (model has paranoid: true also) and no matter what it still deletes the row instead of adding a timestamp to the deletedAt field. I noticed when do any querying it doesn't add the deletedAt = NULL in the query like I've seen in some tutorials. I'm using Sequelize.js v3.29.0.
Model File:
'use strict';
module.exports = function(sequelize, DataTypes) {
var Collection = sequelize.define('Collection', {
userId: {
type: DataTypes.INTEGER,
allowNull: false,
validate: {
isInt: true
}
},
name: {
type: DataTypes.STRING,
allowNull: false
},
description: DataTypes.TEXT,
createdAt: {
allowNull: false,
type: DataTypes.DATE
},
updatedAt: {
allowNull: false,
type: DataTypes.DATE
},
deletedAt: {
type: DataTypes.DATE
}
}, {
classMethods: {
associate: function(models) {
Collection.belongsTo(models.User, { foreignKey: 'userId' })
}
}
}, {
timestamps: true,
paranoid: true
});
return Collection;
};
Migration File:
'use strict';
module.exports = {
up: function(queryInterface, Sequelize) {
return queryInterface.createTable('Collections', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
userId: {
allowNull: false,
type: Sequelize.INTEGER
},
name: {
allowNull: false,
type: Sequelize.STRING
},
description: {
type: Sequelize.TEXT
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
},
deletedAt: {
type: Sequelize.DATE
}
});
},
down: function(queryInterface, Sequelize) {
return queryInterface.dropTable('Collections');
}
};
Here is the code in the controller I'm using to destroy the collection object.
Collection.findOne({
where: {
id: collectionId,
userId: user.id
}
}).then(function(collection){
if (collection !== null) {
collection.destroy().then(function(){
res.redirect('/collection');
}).catch(function(error){
res.redirect('/collection/'+collectionId);
});
}
});
Make sure paranoid is attribute defined inside second object param.
..., {
classMethods: {
associate: function(models) {
Collection.belongsTo(models.User,{ foreignKey: 'userId' })
}
},
timestamps: true,
paranoid: true
}
You've defined paranoid as 3. Param and that is the problem.

Resources