My request SQL fail when I try to insert data in my table PostVotes
I use sequelize migration to migrate my database and I have the same probleme when I make my sql request in my console.
sequelize db:migrate
When I use sequelize.sync() i don't have this problem
My table:
/* TABLE Users */
queryInterface.createTable('Users', {
id: {
allowNull: false,
primaryKey: true,
type: Sequelize.UUID,
defaultValue: Sequelize.UUIDV4,
},
password: {
type: Sequelize.STRING,
allowNull: false,
},
email: {
type: Sequelize.STRING,
allowNull: false,
unique: true,
},
}),
queryInterface.createTable('Posts', {
id: {
allowNull: false,
primaryKey: true,
type: Sequelize.UUID,
defaultValue: Sequelize.UUIDV4,
},
title: {
type: Sequelize.STRING,
allowNull: false,
},
userId: {
type: Sequelize.UUID,
primaryKey: true,
onDelete: 'CASCADE',
references: {
model: 'Users',
key: 'id',
},
},
}),
/* Table posts votes*/
queryInterface.createTable('PostVotes', {
id: {
allowNull: false,
primaryKey: true,
type: Sequelize.UUID,
defaultValue: Sequelize.UUIDV4,
},
vote: {
// eslint-disable-next-line new-cap
type: Sequelize.ENUM('up', 'down'),
validate: {
isIn: [['up', 'down']],
},
allowNull: false,
},
userId: {
type: Sequelize.UUID,
primaryKey: true,
onDelete: 'CASCADE',
references: {
model: 'Users',
key: 'id',
},
},
postId: {
type: Sequelize.UUID,
primaryKey: true,
onDelete: 'CASCADE',
references: {
model: 'Posts',
key: 'id',
},
},
}),
[Error: SQLITE_ERROR: foreign key mismatch - "PostVotes" referencing "Posts"]
I already find answer but nothing is working. I think my mistake is in the table PostVotes but I don't understand what.
Thanks !
FIX
queryInterface.createTable('Posts', {
id: {
allowNull: false,
primaryKey: true,
type: Sequelize.UUID,
defaultValue: Sequelize.UUIDV4,
},
title: {
type: Sequelize.STRING,
allowNull: false,
},
userId: {
type: Sequelize.UUID,
primaryKey: true, # DELETE THIS ONE
onDelete: 'CASCADE',
references: {
model: 'Users',
key: 'id',
},
},
}),
I delete primaryKey in table Post column userId
Related
Tried to create API for internet store using ExpressJS and sequelize. I have users, basket and devices. To connect basket and choosen by user devices used middle table BasketDevice.
Models:
export const Models = {
User: sequelize.define('user',
{
id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
email: { type: DataTypes.STRING, unique: true },
password: { type: DataTypes.STRING },
role: { type: DataTypes.STRING, defaultValue: 'USER' },
isActivated: { type: DataTypes.BOOLEAN, defaultValue: false},
activationLink: { type: DataTypes.STRING, unique: true }
}
),
Basket: sequelize.define('basket',
{
id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
}
),
BasketDevice: sequelize.define('basketDevice',
{
id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
}
),
Device: sequelize.define('device',
{
id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
name: { type: DataTypes.STRING, allowNull: false, unique: true },
price: { type: DataTypes.INTEGER, allowNull: false },
img: { type: DataTypes.STRING, allowNull: false },
rating: { type: DataTypes.INTEGER, defaultValue: 0 },
}
}
Assotiations between tables:
Models.User.hasOne(Models.Basket)
Models.Basket.belongsTo(Models.User)
Models.Basket.hasMany(Models.BasketDevice, {as: 'devices'})
Models.BasketDevice.belongsTo(Models.Basket)
Models.Device.hasMany(Models.BasketDevice)
Models.BasketDevice.belongsTo(Models.Device)
Tryed to give in response basket include basket device
Basket service:
class BasketService {
async getBasket(token: string) {
const userData = await TokenService.verifyRefreshToken(token) as any
const basket = await Models.Basket.findOne({
where: { userId: userData.id },
include: [{model: Models.BasketDevice, as: 'devices'}]
})
return basket
}
}
Don't know how create getBasket function that gives added to cart devices and counting of one device
What is the opltimal way to give devices added in basket?
This is my partner model
const { Sequelize, DataTypes } = require('sequelize');
const sequelize = require('../connection');
const PartnerInfo = sequelize.define(
'partnerinfo',
{
id: {
type: DataTypes.UUID,
allowNull: false,
defaultValue: Sequelize.UUIDV4,
primaryKey: true,
},
name: {
type: DataTypes.STRING,
allowNull: false,
},
email: {
type: DataTypes.STRING,
allowNull: false,
unique: true,
},
phone: {
type: DataTypes.STRING,
allowNull: false,
unique: true,
},
loginSecret: {
type: DataTypes.STRING,
allowNull: true,
},
gender: {
type: DataTypes.INTEGER,
defaultValue: 0, // 0:Female 1:male
},
dob: {
type: DataTypes.STRING,
allowNull: true,
},
image: {
type: DataTypes.STRING,
allowNull: true,
},
type: {
type: DataTypes.INTEGER,
defaultValue: 0, // 0:Value 1:Elite
},
joiningDate: {
type: DataTypes.STRING,
allowNull: false,
},
termination_date: {
type: DataTypes.STRING,
allowNull: true,
},
line1: {
type: DataTypes.STRING,
allowNull: true,
},
line2: {
type: DataTypes.STRING,
allowNull: true,
},
landmark: {
type: DataTypes.STRING,
allowNull: true,
},
city: {
type: DataTypes.STRING,
allowNull: true,
},
state: {
type: DataTypes.STRING,
allowNull: true,
},
country: {
type: DataTypes.STRING,
allowNull: true,
},
pincode: {
type: DataTypes.STRING,
allowNull: true,
},
},
{
timestamps: true,
}
);
module.exports = PartnerInfo;
const { Sequelize, DataTypes } = require('sequelize');
const sequelize = require('../connection');
const PartnerInfo = require('./partnerinfo');
const ServiceArea = require('./servicearea');
const PartnerServiceArea = sequelize.define('partnerservicearea', {
id: {
type: DataTypes.UUID,
allowNull: false,
defaultValue: Sequelize.UUIDV4,
primaryKey: true,
},
partner_id: {
type: DataTypes.UUID,
allowNull: false,
references: {
model: 'partnerinfos',
key: 'id',
},
},
servicearea_id: {
type: DataTypes.CHAR,
allowNull: false,
},
});
PartnerServiceArea.belongsTo(PartnerInfo, {
foreignKey: {
name: 'partner_id',
allowNull: false,
},
targetKey: 'id',
});
PartnerInfo.hasMany(PartnerServiceArea, {
foreignKey: {
name: 'partner_id',
allowNull: false,
},
targetKey: 'id',
onDelete: 'CASCADE',
onUpdate: 'CASCADE',
});
PartnerServiceArea.belongsTo(ServiceArea, {
foreignKey: {
name: 'servicearea_id',
allowNull: false,
},
targetKey: 'id',
onDelete: 'CASCADE',
onUpdate: 'CASCADE',
});
ServiceArea.hasMany(PartnerServiceArea, {
foreignKey: {
name: 'servicearea_id',
allowNull: false,
},
targetKey: 'id',
onDelete: 'CASCADE',
onUpdate: 'CASCADE',
});
module.exports = PartnerServiceArea;
These are the two models I am trying to associate and also using default sync.
I need help with the linking and want to use complex query
This is the SQL query
CREATE TABLE IF NOT EXISTS `partnerserviceareas`
(
`id` CHAR(36) BINARY NOT NULL,
`partner_id` CHAR(36) BINARY NOT NULL,
`servicearea_id` CHAR(255) NOT NULL,
`createdAt` DATETIME NOT NULL,
`updatedAt` DATETIME NOT NULL,
PRIMARY KEY (`id`),
FOREIGN KEY (`partner_id`) REFERENCES `partnerinfos` (`id`)
ON DELETE NO ACTION ON UPDATE CASCADE,
FOREIGN KEY (`servicearea_id`) REFERENCES `service_areas` (`id`)
ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB;
and the error is
Referencing column 'partner_id' and referenced column 'id' in foreign key constraint 'partnerserviceareas_ibfk_1' are incompatible
Please check "charter set" and "collation" on the both related fields, if data type is "string/char" type.
There is no such problem ("foreign key constraint 'xxx' are incompatible") on integer data type (or at least I have not met such incompatibles).
Sometimes created table has different "charter set/collation" from foreign tables (foreign table created by others, restored from old dump etc).
If create new table (charter/collation to be same as foreign table):
CREATE TABLE IF NOT EXISTS `partnerserviceareas` (
...
)
DEFAULT CHARACTER SET = utf8mb4
COLLATE = utf8mb4_unicode_ci;
If you have already both tables and would like to change a column:
ALTER TABLE `partnerserviceareas`
CHANGE COLUMN `partner_id` `partner_id` CHAR(36)
CHARACTER SET 'utf8mb4'
COLLATE 'utf8mb4_unicode_ci' NOT NULL ;
I would like to add a constraint inside my migration file, for example when I try and delete a row and there's another row inside another table that's referencing the row i'm deleting it needs to throw an error. There will also be multiple tables that will associate with the table.
return queryInterface.createTable('status', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
name: {
type: Sequelize.STRING,
unique: true
},
slug: {
type: Sequelize.STRING,
unique: true
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
},
});
table status:
...
id
table locales:
...
id_status
table users
...
id_status
id_status: {
type: Sequelize.INTEGER,
references: {
model: 'status',
key: 'id',
onDelete: 'restrict'
}
},
id_status: {
type: Sequelize.INTEGER,
references: {
model: 'status',
key: 'id',
},
onDelete: 'restrict'
},
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 },
}],
})
I have some issue with getting full data from db.
That are my models:
User
module.exports = function(sequelize, DataTypes) {
return sequelize.define('user', {
id: {
type: DataTypes.INTEGER(11),
allowNull: false,
primaryKey: true,
autoIncrement: true,
field: 'ID'
},
password: {
type: DataTypes.STRING(255),
allowNull: false,
field: 'password'
},
email: {
type: DataTypes.STRING(255),
allowNull: false,
unique: true,
field: 'email'
},
roleId: {
type: DataTypes.INTEGER(11),
allowNull: false,
references: {
model: 'role',
key: 'ID'
},
field: 'role_id'
}
}, {
timestamps: false,
tableName: 'user'
});
};
Role
module.exports = function(sequelize, DataTypes) {
return sequelize.define('role', {
id: {
type: DataTypes.INTEGER(11),
allowNull: false,
primaryKey: true,
autoIncrement: true,
field: 'ID'
},
name: {
type: DataTypes.STRING(255),
allowNull: false,
unique: true,
field: 'name'
},
description: {
type: DataTypes.STRING(255),
allowNull: false,
field: 'description'
},
permission: {
type: DataTypes.INTEGER(11),
allowNull: false,
field: 'permission'
}
}, {
timestamps: false,
tableName: 'role',
});};
I want to get object of one specific user including all role content.
Somethink like
{
id: 4,
password: 'xxx',
email: 'adsads#saas.com',
role: {
id: 2,
name: 'admin'
description: 'ipsum ssaffa',
permission: 30
}
}
So I'm using:
User.findOne( { where: { id: req.userId }, include: [ Role ] } ).then( user =>{...});
but I get in the result err.message: "role is not associated to user"
And the simple question - what's wrong ? :)
*to handle models I'm using sequelize-cli
You get this error because you didn't add associate between the models
base on your json I see that each user only has one role, so you can either use belongsTo in role model or hasOne in user model
Should be something like this:
User.js
module.exports = function(sequelize, DataTypes) {
var user = sequelize.define('user', {
id: {
type: DataTypes.INTEGER(11),
allowNull: false,
primaryKey: true,
autoIncrement: true,
field: 'ID'
},
password: {
type: DataTypes.STRING(255),
allowNull: false,
field: 'password'
},
email: {
type: DataTypes.STRING(255),
allowNull: false,
unique: true,
field: 'email'
},
roleId: {
type: DataTypes.INTEGER(11),
allowNull: false,
references: {
model: 'role',
key: 'ID'
},
field: 'role_id'
}
}, {
timestamps: false,
tableName: 'user'
});
user.associate = function(models) {
user.hasOne(models.role, {foreignKey: 'id',sourceKey: 'roleId'});
}
return user;
};
Role.js
module.exports = function(sequelize, DataTypes) {
var role = sequelize.define('role', {
id: {
type: DataTypes.INTEGER(11),
allowNull: false,
primaryKey: true,
autoIncrement: true,
field: 'ID'
},
name: {
type: DataTypes.STRING(255),
allowNull: false,
unique: true,
field: 'name'
},
description: {
type: DataTypes.STRING(255),
allowNull: false,
field: 'description'
},
permission: {
type: DataTypes.INTEGER(11),
allowNull: false,
field: 'permission'
}
}, {
timestamps: false,
tableName: 'role',
});
role.associate = function(models) {
user.belongsTo(models.role, {foreignKey: 'id'});
}
return role;
};
You have to declare associations between your Models. If using Sequelize CLI make sure the static method associate is being called. Example:
/models.index.js
const Category = require('./Category');
const Product = require('./Product');
const ProductTag = require('./ProductTag');
const Tag = require('./Tag');
Category.associate({Product});
Product.associate({Category,Tag});
Tag.associate({Product});
module.exports={Category,Product,ProductTag,Tag};
and then the association in Category.js
'use strict';
const {Model,DataTypes} = require('sequelize');
const sequelize = require('../config/connection.js');
class Category extends Model {
/**
* Helper method for defining associations.
* This method is not a part of Sequelize lifecycle.
* The `models/index` file will call this method.
*/
static associate({Product}) {
// define association here
console.log('Category associated with: Product');
this.hasMany(Product, {
foreignKey: 'category_id',
onDelete: 'CASCADE'
});
}
}
Category.init({
category_id: {type: DataTypes.INTEGER, autoIncrement: true, allowNull: false, primaryKey: true},
category_name: {type: DataTypes.STRING, allowNull: false}
}, {
sequelize,
timestamps: false,
freezeTableName: true,
underscored: true,
modelName: "Category",
});
module.exports = Category;