Cannot add foreign key constraints - javascript

I have checked this answer and made sure with both scenario are correct. But still having issue creating constraints:
Model:
user.js
'use strict';
module.exports = (sequelize, DataTypes) => {
const User = sequelize.define('User', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: DataTypes.INTEGER
},
username: {
type: DataTypes.STRING,
unique: true,
allowNull: false
},
password: {
type: DataTypes.STRING,
allowNull: false
}
}, {});
User.associate = function(models) {
models.User.hasMany(models.Answer);
};
return User;
};
answer.js
'use strict';
module.exports = (sequelize, DataTypes) => {
const Answer = sequelize.define('Answer', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: DataTypes.INTEGER
},
userId: {
type: DataTypes.INTEGER,
references: {
model: 'Users',
key: 'id'
},
allowNull: true
},
content: DataTypes.TEXT
}, {});
Answer.associate = function(models) {
models.belongsTo(models.User)
};
return Answer;
};
Migration
...-create-user.js
'use strict';
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.createTable('Users', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
username: {
type: Sequelize.STRING,
unique: true,
allowNull: false
},
password: {
type: Sequelize.STRING,
allowNull: false
}
});
},
down: (queryInterface, Sequelize) => {
return queryInterface.dropTable('Users');
}
};
...create-answer.js
'use strict';
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.createTable('Answers', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
userId: {
allowNull: true,
type: Sequelize.INTEGER
},
content: {
allowNull: false,
type: Sequelize.TEXT
}
});
},
down: (queryInterface, Sequelize) => {
return queryInterface.dropTable('Answers');
}
};
What else might be the issue? Is it due to allowNull: true? But I am sure this should not be the case because I also tested using allowNull: false if it works, but it did not.
I have also tried model: User and .INTEGER(11) exactly but nothing work. I cannot see foreign key constraints on PHPMyAdmin.

You should add
userId: {
type: Sequelize.INTEGER,
references: {
model: 'Users',
key: 'id'
},
allowNull: true
}
in create-answer.js
instead of
userId: {
allowNull: true,
type: Sequelize.INTEGER
},

Related

Sequelize association create new row

I wrote here yesterday, but I did not find the right solution,
I have such a connection (pictures 1)
How can I change my code so that I would create a sizeChart, bind sizeChartParameters to it, and sizeChartAttributes to it? I use sequelizeORM
Now there is a record only in sizeChart
const findChart = await models.sizeChart.create({
categoryId:categoryId,
nameChart:sizeChartName,
include:[{
required:true,
model:models.sizeChartParameters,
attributeValue:attributeValue,
include:[{
required:true,
model:models.sizeChartAttributes,
attributeName:attributeName,
}]
}]
});
sizeChart table
module.exports = function (sequelize, Sequelize) {
const SizeChart = sequelize.define('sizeChart', {
id: {
type: Sequelize.INTEGER,
autoIncrement: true,
primaryKey: true,
allowNull: false,
},
categoryId:{
type: Sequelize.INTEGER,
allowNull: false,
},
nameChart:{
type: Sequelize.TEXT,
allowNull: false,
},
});
SizeChart.associate = function (models) {
SizeChart.belongsTo(models['sizeChartParameters']);
};
return SizeChart;
};
sizeChartParameters table
module.exports = function(sequelize, Sequelize) {
const SizeChart = sequelize.define('sizeChartParameters', {
id: {
type: Sequelize.INTEGER,
autoIncrement: true,
primaryKey: true,
allowNull: false,
},
attributeValue: {
type: Sequelize.TEXT,
allowNull: false,
},
});
return SizeChart;
};
sizeChartAttributes table
module.exports = function(sequelize, Sequelize) {
const SizeChart = sequelize.define('sizeChartAttributes', {
id: {
type: Sequelize.INTEGER,
autoIncrement: true,
primaryKey: true,
allowNull: false,
},
attributeName: {
type: Sequelize.TEXT,
allowNull: false,
},
});
SizeChart.associate = function(models) {
SizeChart.hasOne(models['sizeChartParameters'],{foreignKey:'attributeId'});
};
return SizeChart;
};
const findChart = await models.sizeChart.create({
categoryId:categoryId,
nameChart:sizeChartName,
include:[{
required:true,
model:models.sizeChartParameters,
attributeValue:attributeValue,
include:[{
required:true,
model:models.sizeChartAttributes,
attributeName:attributeName,
}]
}]
});

Sequelise : Many To Many table(CROSS TABLE) associated to other table

This is my Diagram DATABASE : https://i.stack.imgur.com/CGAwh.png
I made models of my databases with SEQUELIZE like that :
MODEL : Level
module.exports = (sequelize, DataTypes) => {
const Level = sequelize.define(
'Level',
{
level_id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
label: {
type: DataTypes.STRING,
allowNull: false,
unique: {
args: true,
msg: 'Level:Label already exist!',
},
validate: {
notEmpty: { msg: `Level:Label cannot be empty!` },
notNull: { msg: `Level:Label cannot be NULL!` },
},
},
ref: {
type: DataTypes.STRING,
allowNull: true,
},
description: {
type: DataTypes.TEXT,
allowNull: true,
},
},
{
tableName: 'levels',
timestamps: false,
}
);
Level.associate = (models) => {
Level.belongsToMany(models.Test, {
through: models.testHasLevel,
foreignKey: 'level_id',
otherKey: 'test_id',
timestamps: false,
});
};
return Level;
};
Model : TEST :
module.exports = (sequelize, DataTypes) => {
const Test = sequelize.define(
'Test',
{
test_id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
label: {
type: DataTypes.STRING,
allowNull: false,
validate: {
notEmpty: { msg: `Test:label cannot be empty!` },
notNull: { msg: `Test:label cannot be NULL!` },
},
},
isInternal: {
type: DataTypes.BOOLEAN,
defaultValue: false,
allowNull: false,
validate: {
notEmpty: { msg: `Test:isInternal cannot be empty!` },
notNull: { msg: `Test:isInternal cannot be NULL!` },
},
},
parent_id: {
type: DataTypes.INTEGER,
defaultValue: null,
allowNull: true,
},
},
{
tableName: 'tests',
timestamps: false,
}
);
Test.associate = (models) => {
Test.belongsToMany(models.Level, {
through: models.testHasLevel,
foreignKey: 'test_id',
otherKey: 'level_id',
timestamps: false,
});
Test.hasMany(models.Test, { foreignKey: 'parent_id', as: 'children' });
};
return Test;
};
MODEL : TEST HAS MODEL
module.exports = (sequelize, DataTypes) => {
const testHasLevel = sequelize.define(
'testHasLevel',
{},
{
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
tableName: 'test_has_level',
timestamps: false,
}
);
testHasLevel.associate = (models) => {
testHasLevel.belongsTo(models.Test, {
foreignKey: 'test_id',
targetKey: 'test_id',
});
testHasLevel.belongsTo(models.Level, {
foreignKey: 'level_id',
targetKey: 'level_id',
});
};
return testHasLevel;
};
I made also SESSION MODEL :
module.exports = (sequelize, DataTypes) => {
const Session = sequelize.define(
'Session',
{
session_id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
institut_id: {
type: DataTypes.INTEGER,
},
start: {
type: DataTypes.DATE,
},
end: {
type: DataTypes.DATE,
},
test_id: {
type: DataTypes.INTEGER,
},
level_id: {
type: DataTypes.INTEGER,
},
limitDateSubscribe: {
type: DataTypes.DATE,
},
placeAvailable: {
type: DataTypes.INTEGER,
},
},
{
tableName: 'sessions',
timestamps: false,
}
);
Session.associate = (models) => {
Session.hasMany(models.sessionHasUser, { foreignKey: 'session_id' });
};
return Session;
};
But i have no idea how to "BIND" SESSION with TEST_HAS_LEVEL with Sequelize ....
What should i change ? cause i know "composite key" are not allowed with the last version of sequelize.
In other term :
How associate properly a cross table with a one to many relationship to an other table ?
Model: Level
module.exports = (sequelize, DataTypes) => {
const Level = sequelize.define(
"Level",
{
level_id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
label: {
type: DataTypes.STRING,
allowNull: false,
unique: {
args: true,
msg: "Level:Label already exist!",
},
validate: {
notEmpty: { msg: `Level:Label cannot be empty!` },
notNull: { msg: `Level:Label cannot be NULL!` },
},
},
ref: {
type: DataTypes.STRING,
allowNull: true,
},
description: {
type: DataTypes.TEXT,
allowNull: true,
},
},
{
tableName: "levels",
timestamps: false,
}
);
Level.associate = (models) => {
Level.hasMany(models.testHasLevel, {
foreignKey: "level_level_id",
as: "levels",
});
};
return Level;
};
Model: Test
module.exports = (sequelize, DataTypes) => {
const Test = sequelize.define(
"Test",
{
test_id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
label: {
type: DataTypes.STRING,
allowNull: false,
validate: {
notEmpty: { msg: `Test:label cannot be empty!` },
notNull: { msg: `Test:label cannot be NULL!` },
},
},
isInternal: {
type: DataTypes.BOOLEAN,
defaultValue: false,
allowNull: false,
validate: {
notEmpty: { msg: `Test:isInternal cannot be empty!` },
notNull: { msg: `Test:isInternal cannot be NULL!` },
},
},
parent_id: {
type: DataTypes.INTEGER,
defaultValue: null,
allowNull: true,
},
},
{
tableName: "tests",
timestamps: false,
}
);
Test.associate = (models) => {
Test.hasMany(models.testHasLevel, {
foreignKey: "test_test_id",
as: "tests",
});
Test.hasMany(models.Test, { foreignKey: "parent_id", as: "children" });
};
return Test;
};
Model: Test has level
module.exports = (sequelize, DataTypes) => {
const testHasLevel = sequelize.define(
"testHasLevel",
{
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
test_test_id: {
type: DataTypes.INTEGER,
},
level_level_id: {
type: DataTypes.INTEGER,
},
},
{
tableName: "test_has_level",
timestamps: false,
}
);
testHasLevel.associate = (models) => {
testHasLevel.belongsTo(models.Test, {
foreignKey: "test_test_id",
as: "tests",
});
testHasLevel.belongsTo(models.Level, {
foreignKey: "level_level_id",
as: "levels",
});
testHasLevel.hasMany(models.Session, {
foreignKey: "test_has_level_id",
as: "test_has_level",
});
};
return testHasLevel;
};
Model: Session
module.exports = (sequelize, DataTypes) => {
const Session = sequelize.define(
"Session",
{
session_id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
institut_id: {
type: DataTypes.INTEGER,
},
start: {
type: DataTypes.DATE,
},
end: {
type: DataTypes.DATE,
},
test_has_level_id: {
type: DataTypes.INTEGER,
},
limitDateSubscribe: {
type: DataTypes.DATE,
},
placeAvailable: {
type: DataTypes.INTEGER,
},
},
{
tableName: "sessions",
timestamps: false,
}
);
Session.associate = (models) => {
Session.belongsTo(models.testHasLevel, {
foreignKey: "test_has_level_id",
as: "test_has_level",
});
};
return Session;
};

EagerLoadingError [SequelizeEagerLoadingError]: grl_entidade is not associated to stn_matriz_gerada

I have this error and can`t find a way arround it: EagerLoadingError [SequelizeEagerLoadingError]: grl_entidade is not associated to stn_matriz_gerada!
I have tryed many things, currently this is the way my app is:
stn_matriz_gerada.js
const Sequelize = require('sequelize');
module.exports = function(sequelize, DataTypes) {
return sequelize.define('stn_matriz_gerada', {
conta: {
type: DataTypes.STRING,
allowNull: true,
primaryKey: true
},
v1: {
type: DataTypes.STRING,
allowNull: true
},
t1: {
type: DataTypes.STRING,
allowNull: true
},
v2: {
type: DataTypes.STRING,
allowNull: true
},
t2: {
type: DataTypes.STRING,
allowNull: true
},
v3: {
type: DataTypes.STRING,
allowNull: true
},
t3: {
type: DataTypes.STRING,
allowNull: true
},
v4: {
type: DataTypes.STRING,
allowNull: true
},
t4: {
type: DataTypes.STRING,
allowNull: true
},
v5: {
type: DataTypes.STRING,
allowNull: true
},
t5: {
type: DataTypes.STRING,
allowNull: true
},
v6: {
type: DataTypes.STRING,
allowNull: true
},
t6: {
type: DataTypes.STRING,
allowNull: true
},
v7: {
type: DataTypes.STRING,
allowNull: true
},
t7: {
type: DataTypes.STRING,
allowNull: true
},
valor: {
type: DataTypes.DOUBLE,
allowNull: true
},
tipo: {
type: DataTypes.STRING,
allowNull: true
},
tipo_int: {
type: DataTypes.INTEGER,
allowNull: true
},
natureza_valor: {
type: DataTypes.STRING,
allowNull: true
},
exercicio: {
type: DataTypes.INTEGER,
allowNull: true
},
mes: {
type: DataTypes.INTEGER,
allowNull: true
},
grl_entidade: {
type: DataTypes.INTEGER,
allowNull: true,
references: {
model: 'grl_entidade',
key: 'id'
}
},
conteudo_txt: {
type: DataTypes.TEXT,
allowNull: true
}
}, {
sequelize,
tableName: 'stn_matriz_gerada',
schema: 'public',
timestamps: false
});
};
init-models.js
var DataTypes = require("sequelize").DataTypes;
var _grl_entidade = require("./grl_entidade");
var _grl_entidade_tipo = require("./grl_entidade_tipo");
var _grl_municipio = require("./grl_municipio");
var _grl_uf = require("./grl_uf");
var _stn_matriz_gerada = require("./stn_matriz_gerada");
function initModels(sequelize) {
var grl_entidade = _grl_entidade(sequelize, DataTypes);
var grl_entidade_tipo = _grl_entidade_tipo(sequelize, DataTypes);
var grl_municipio = _grl_municipio(sequelize, DataTypes);
var grl_uf = _grl_uf(sequelize, DataTypes);
var stn_matriz_gerada = _stn_matriz_gerada(sequelize, DataTypes);
grl_entidade_tipo.hasMany(grl_entidade,
{ foreignKey: { name: "grl_entidade_tipo"},
as: "grl_entidade_tipo_fk"},);
grl_entidade.belongsTo(grl_entidade_tipo,
{ foreignKey: { name: "grl_entidade_tipo"},
as: "grl_entidade_tipo_fk"},);
grl_municipio.hasMany(grl_entidade,
{ foreignKey: { name: "grl_municipio"},
as: "grl_municipio_fk"},);
grl_entidade.belongsTo(grl_municipio,
{ foreignKey: { name: "grl_municipio"},
as: "grl_municipio_fk"},);
grl_uf.hasMany(grl_municipio,
{ foreignKey: { name: "grl_uf"},
as: "grl_uf_fk"},);
grl_municipio.belongsTo(grl_uf,
{ foreignKey: { name: "grl_uf"},
as: "grl_uf_fk"},);
grl_entidade.hasMany(stn_matriz_gerada,
{ foreignKey: { name: "grl_entidade"},
as: "grl_entidade_fk"},);
stn_matriz_gerada.belongsTo(grl_entidade,
{ foreignKey: { name: "grl_entidade"},
as: "grl_entidade_fk"},);
return {
grl_entidade,
grl_entidade_tipo,
grl_municipio,
grl_uf,
stn_matriz_gerada,
};
}
module.exports = initModels;
module.exports.initModels = initModels;
module.exports.default = initModels;
MscService.js
class MscService {
static async getAllMscs() {
try {
return await database.stn_matriz_gerada.findAll();
} catch (error) {
throw error;
}
}
static async getAMsc(conta) {
try {
const theMsc = await database.stn_matriz_gerada.findAll({
where: { conta: Number(conta) },
include: [ {model: database.grl_entidade, as: 'grl_entidade_fk' }]
});
return theMsc;
} catch (error) {
console.log(error);
throw error;
}
}
}
export default MscService;
It has hasMany and belongsTo but stills give me the error of EagerLoadingError [SequelizeEagerLoadingError]: grl_entidade is not associated to stn_matriz_gerada!
Version: "sequelize": "^6.3.5",
Can anyone help me please?

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 },
}],
})

Query sequelize table without column 'id'

I have the following model
(Migration) transaction.js
'use strict';
module.exports = {
up: function(queryInterface, Sequelize) {
return queryInterface.createTable('transactions', {
date: {
type: Sequelize.DATEONLY
},
transNo: {
type: Sequelize.INTEGER,
allowNull: false,
autoIncrement: true,
primaryKey: true,
},
accNo: {
type: Sequelize.INTEGER
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
});
},
down: function(queryInterface, Sequelize) {
return queryInterface.dropTable('transactions');
}
};
(Model) transaction.js
'use strict';
const credit = require('./credit.js');
module.exports = function(sequelize, DataTypes) {
var transaction = sequelize.define('transaction', {
date: DataTypes.DATEONLY,
transNo: DataTypes.INTEGER,
accNo: DataTypes.INTEGER
}, {
classMethods: {
associate: function(models) {
// associations can be defined here
transaction.hasOne(models.credit, {foreignKey: 'transNo'});
}
}
});
return transaction;
};
(Model) credit.js
module.exports = function(sequelize, DataTypes) {
var credit = sequelize.define('credit', {
transNo: DataTypes.INTEGER,
creNo: DataTypes.INTEGER
}, {
classMethods: {
associate: function(models) {
// associations can be defined here
}
}
});
return credit;
};
(Migration) credit.js
` module.exports = {
up: function(queryInterface, Sequelize) {
return queryInterface.createTable('credits', {
transNo: {
type: Sequelize.INTEGER
},
creNo: {
type: Sequelize.INTEGER,
autoIncrement: true,
allowNull: false,
primaryKey: true
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
});
},
down: function(queryInterface, Sequelize) {
return queryInterface.dropTable('credits');
}
};`
it still queries with the id column
Executing (default): SELECT transaction.id, transaction.date, transaction.accNo,.........(and so on).
how to disable the id column from being queried?
You simply need to set another column as your primary key and the id column won't be generated by default.
module.exports = function(sequelize, DataTypes) {
var credit = sequelize.define('credit', {
transNo: DataTypes.INTEGER,
{
creNo: DataTypes.INTEGER,
primaryKey: true //define a primaryKey
}
}, {
classMethods: {
associate: function(models) {
// associations can be defined here
}
}
});
return credit;
};

Categories