I have my models all set up, and I have a foreign key from one table to another using the tables ID. I also want to have the url property as a foreign key, but whenever I include "type: DataTypes.STRING', I get the following error
Unhandled rejection SequelizeDatabaseError: (conn=195, no: 1215, SQLState: HY000) Cannot add foreign key constraint
When I don't include the datatype, it adds the FK, but as an integer. How can I create a FK that specifically references the URL property?
Thanks
categories.belongsTo(categoriesTop, {
foreignKey: {
name: 'topCategoriesUrl',
allowNull: false,
type: DataTypes.STRING,
referencesKey: "url"
}
});
Categories_top schema
const { Sequelize, DataTypes } = require('sequelize');
const db = require('../dbconfig');
const categories_top = db.define('categories_top', {
url: {
type: DataTypes.STRING,
allowNull: false
},
title: {
type: DataTypes.STRING,
allowNull: false
},
subtitle: {
type: DataTypes.STRING,
allowNull: false
},
image: {
type: DataTypes.STRING
}
}, {
freezeTableName: true,
timestamps: false
});
module.exports = categories_top;
categories schema
const { Sequelize, DataTypes } = require('sequelize');
const db = require('../dbconfig');
const topCategories = require('./category_top');
const categories = db.define('categories', {
title: {
type: DataTypes.STRING,
allowNull: false
},
subtitle: {
type: DataTypes.STRING,
allowNull: true
},
url: {
type: DataTypes.STRING,
allowNull: false
},
image: {
type: DataTypes.STRING
}
}, {
freezeTableName: true,
timestamps: false
});
module.exports = categories;
You have to define url in category_top as a primary key or a unique constraint, like this:
const categories_top = db.define('categories_top', {
url: {
type: DataTypes.STRING,
allowNull: false,
primaryKey: true, // Either define it as a primary key
unique: true // OR as a unique constraint
},
title: {
type: DataTypes.STRING,
allowNull: false
},
subtitle: {
type: DataTypes.STRING,
allowNull: false
},
image: {
type: DataTypes.STRING
}
}, {
freezeTableName: true,
timestamps: false
});
Read more about foreign keys here.
Related
So I've been trying to build a medium-clone for a project and therefore, I need to make a 1 : N relation for my "User" and "Article" Tables. But when I add the association Article.belongsTo(User); , I receive an error stating Error: Article.belongsTo called with something that's not a subclass of Sequelize.Model , and any kind of help would be highly appreciated.
Here's my code :
Article.js
const {Sequelize, DataTypes} = require('sequelize');
const db = require('../../config/Database');
const User = require('../User/User');
const Article = db.define('Article', {
slug : {
type: DataTypes.STRING(30),
allowNull: false,
primaryKey: true,
unique: true
},
title : {
type: DataTypes.STRING(50),
allowNull: false
},
description : {
type: DataTypes.STRING(100)
},
body : {
type: DataTypes.STRING
},
createdAt : {
allowNull: false,
type: DataTypes.DATE,
defaultValue: DataTypes.NOW
},
updatedAt : {
allowNull: false,
type: DataTypes.DATE,
defaultValue: DataTypes.NOW
},
favorited : {
type : DataTypes.BOOLEAN,
defaultValue: 0
},
favoritesCount : {
type : DataTypes.INTEGER,
defaultValue : 0
}
},{
freezeTableName: true
})
Article.belongsTo(User);
module.exports = Article;
User.js
const {Sequelize,DataTypes} = require('sequelize');
const db = require('../../config/Database');
const Article = require('../Article/Article');
const User = db.define('User', {
email: {
type: DataTypes.STRING,
allowNull: false,
primaryKey: true,
unique: true
},
username: {
type: DataTypes.STRING,
allowNull: false,
unique: true
},
password: {
type: DataTypes.STRING,
allowNull: false
},
bio: {
type: DataTypes.STRING(100),
allowNull: true
},
image: {
type: DataTypes.STRING,
allowNull: true
},
token: {
type: DataTypes.STRING
}
},{
freezeTableName: true
})
User.hasMany(Article);
module.exports = User;
I'm stuck with this problem for quite some time now and I don't know what's wrong with my code I'm trying to associate one table to another but only half of it works any help would be greatly appreciated.
models/companies.js
const DataTypes = require('sequelize');
const sequelize = require('../config/database');
const Users = require('./users');
const Companies = sequelize.define(
'companies',
{
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: DataTypes.INTEGER
},
name: {
type: DataTypes.STRING(50),
unique: true,
allowNull: false
},
image_url: {
type: DataTypes.STRING(100),
unique: true
},
created_at: {
allowNull: true,
type: DataTypes.DATE,
defaultValue: Date.now()
},
updated_at: {
allowNull: true,
type: DataTypes.DATE,
defaultValue: Date.now()
}
},
{
//Rewrite default behavior of sequelize
timestamps: false,
paranoid: true,
underscored: true
}
);
Companies.hasMany(Users);
Users.belongsTo(Companies);
Companies.sync();
module.exports = Companies;
models/users.js
const DataTypes = require('sequelize');
const sequelize = require('../config/database');
const Users = sequelize.define(
'users',
{
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: DataTypes.INTEGER
},
name: {
type: DataTypes.STRING(40),
allowNull: false
},
email: {
type: DataTypes.STRING(60),
allowNull: false,
unique: true
},
password: {
type: DataTypes.STRING(60)
},
role: {
type: DataTypes.STRING(40),
allowNull: false
},
image_url: {
type: DataTypes.STRING(100),
unique: true
},
batch: {
type: DataTypes.STRING(3)
},
major: {
type: DataTypes.STRING(10)
},
company_id: {
type: DataTypes.INTEGER,
allowNull: false
},
created_at: {
allowNull: true,
type: DataTypes.DATE,
defaultValue: Date.now()
},
updated_at: {
allowNull: true,
type: DataTypes.DATE,
defaultValue: Date.now()
}
},
{
//Rewrite default behavior of sequelize
timestamps: false,
paranoid: true,
underscored: true
}
);
Users.sync();
module.exports = Users;
Then after I try to run this code below
const Companies = require('./database/models/companies');
const Users = require('./database/models/Users');
//Relation 1: Company and Users
Companies.findAll({ include: [ Users ] }).then((res) => console.log(res));
Users.findAll({ include: [ Companies ] }).then((res) => console.log(res));
it gives me this error:
(node:4893) UnhandledPromiseRejectionWarning: SequelizeEagerLoadingError: companies is not associated to users!
I've tried a couple of solutions online but it didn't help in this case.
BelongsTo means one to one relationship while a company may have multiple users (meaning, calling BelongsTo after hasMany collide!).
For more: https://sequelize.org/master/manual/assocs.html
In my application every user can record many temperatures, but one temperature record should have only one user. I am trying to execute the following code and facing an 'User is not associated with Temperature' Error. Please review my code below and let me know where i have gone wrong.
This is my User model
const { Sequelize, DataTypes, Model } = require('sequelize');
const sequelize = require('../connection');
var Temperature = require('./temperature');
var User = sequelize.define('User', {
id: {
type: Sequelize.INTEGER,
autoIncrement: true,
primaryKey: true,
},
firstName: {
type: DataTypes.STRING,
allowNull: false
},
lastName: {
type: DataTypes.STRING,
allowNull: false
},
email: {
type: DataTypes.STRING,
allowNull: false
},
password: {
type: DataTypes.STRING,
allowNull: false
},
status: {
type: DataTypes.STRING,
allowNull: false,
defaultValue: 'Active'
},
role: {
type: DataTypes.STRING,
allowNull: false,
defaultValue: 'Admin'
}
});
User.associate = (models) => {
User.hasMany(models.Temperature, { as: 'temperatures' })
}
module.exports = User;
This is my Temperature model
const { Sequelize, DataTypes, Model } = require('sequelize');
const sequelize = require('../connection');
const User = require('./users');
var Temperature = sequelize.define('Temperature', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
},
userId: {
type: DataTypes.INTEGER,
allowNull: false,
},
temperature: {
type: DataTypes.FLOAT,
allowNull: false
},
recordDateTime: {
type: DataTypes.DATE,
allowNull: false
}
});
Temperature.associate = (models) => {
Temperature.belongsTo(models.User, { foreignKey: 'userId', as: 'user' })
}
module.exports = Temperature;
I am getting error in running the following code
Temperature.findAll({ include: User, raw:true})
.then((res)=>{
console.log(res);
})
Can you anyone please help in figuring out this issue.
The associate functions in both the models are not executing.
you don't need to add userId column into Temperature model schema, just define associations as you have already did and even if you want to add userId column in model schema the do it like below but must add it in migration file of your Temperature model schema like below
userId: {
type: Sequelize.INTEGER,
allowNull: false,
references: {
model: 'Users', // <----- name of the table
key: 'id' // <----- primary key
}
}
i have these 2 models:
module.exports = function(sequelize, DataTypes) {
return sequelize.define('services_prices', {
id: {
type: DataTypes.INTEGER(11),
allowNull: false,
primaryKey: true
},
service_id: {
type: DataTypes.INTEGER(11),
allowNull: true,
references: {
model: 'services',
key: 'id'
}
},
created_at: {
type: DataTypes.DATE,
allowNull: false
},
limit: {
type: DataTypes.INTEGER(11),
allowNull: true
},
price: {
type: DataTypes.INTEGER(11),
allowNull: true
}
});
};
which is parent of this model: (services_user_prices can override services_prices )
module.exports = function(sequelize, DataTypes) {
return sequelize.define('services_user_prices', {
id: {
type: DataTypes.INTEGER(11),
allowNull: false,
primaryKey: true,
autoIncrement: true
},
user_id: {
type: DataTypes.INTEGER(11),
allowNull: true
},
created_at: {
type: DataTypes.DATE,
allowNull: false
},
currency: {
type: DataTypes.STRING(255),
allowNull: true
},
is_active: {
type: DataTypes.INTEGER(1),
allowNull: true,
defaultValue: '0'
},
is_trial: {
type: DataTypes.INTEGER(1),
allowNull: true,
defaultValue: '0'
},
start_date: {
type: DataTypes.DATE,
allowNull: false
},
end_date: {
type: DataTypes.DATE,
allowNull: true
},
price: {
type: DataTypes.INTEGER(11),
allowNull: true
},
bundle_price_id: {
type: DataTypes.INTEGER(11),
allowNull: true,
references: {
model: 'services_prices',
key: 'id'
}
}
});
};
when trying to join them i get an error:
EagerLoadingError: services_prices is not associated to services_user_prices!
const result= await db.services_user_prices.findOne({
where: { is_active: 1, user_id: 123 }, include:[{db.services_prices}]
});
in the db services_user_prices has foreign key to services_prices table
what am i doing wrong?
Well if you are using sequelize then you need to update your model because
by default, sequelize will be looking for foreign key starts with model name like
you have defined bundle_price_id as a foreign key for services_prices.
You need to change your column name to services_price_id then it will get fixed.
or if you want to use bundle_price_id you need to define it in your model relation as.
Model.belongsTo(models.ModelName, { foreignKey: 'your_key'} )
Please feel free if you need to ask anything else.
As complement of the above answer you need to add an identifier with as: on the association like this:
Model.belongsTo(models.ModelName, { foreignKey: 'your_key', as:'your_identifier' } )
Then when you do the include on the method you also call the identifier:
await db.services_user_prices.findOne({
where: { is_active: 1, user_id: 123 },
include:[{
model: db.services_prices
as: 'your_identifier'
}]
});
If you don't define the foreignKey field, the as field will set the column name.
I am trying to create an association in sequelize 4, table is getting created but the foreign key reference is not happening.
const Sequelize = require("sequelize");
const db = require("../config/db.js");
const ValidationList = require("./validation_list.js");
const AppList = db.define("app_list", {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
},
application: {
type: Sequelize.STRING,
allowNull: false
},
environment: {
type: Sequelize.STRING,
allowNull: false
},
instance_name: {
type: Sequelize.STRING,
allowNull: false
},
url: {
type: Sequelize.STRING,
allowNull: true
}
});
AppList.associate = function (models) {
AppList.belongsTo(models.ValidationList, {
foreignKey: 'application',
targetKey: 'application_name'
});
};
module.exports = AppList;
Is it something am doing wrong here?
model validation_list.js is also similar to app_list.js
const db = require("../config/db.js");
const Sequelize = require("sequelize");
const ValidationList = db.define("validation_list", {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
},
os: {
type: Sequelize.STRING,
allowNull: true
},
caac_folder_id: {
type: Sequelize.STRING,
allowNull: false
},
application_name: {
type: Sequelize.STRING,
allowNull: false,
unique: true
}
});
module.exports = ValidationList;
Here is the validation_list model.