SQLite SequelizeJs adding an extra filed in query - node.js

I am using sequelize and SQLite3. When I use the model in my code then it is generating wrong query. Can any one help me to fix this issue
This is my model defiantion
module.exports = function(sequelize, DataTypes) {
let product = sequelize.define('product', {
id: {
type: DataTypes.INTEGER(10).UNSIGNED,
primaryKey: true,
autoIncrement: true
},
name: {
type: DataTypes.STRING(200),
},
code: {
type: DataTypes.STRING(100),
},
desc: {
type: "BLOB",
},
productCategoryId: {
type: DataTypes.INTEGER(10).UNSIGNED,
references: {
model: 'product_category',
key: 'id'
}
},
costPrice: {
type: DataTypes.FLOAT,
},
sellPrice: {
type: DataTypes.FLOAT,
},
markup: {
type: DataTypes.FLOAT,
},
markupType: {
type: DataTypes.ENUM('AMOUNT','PERCENTAGE'),
},
imgAttachment: {
type: DataTypes.INTEGER(1),
},
minOrderQuantity: {
type: DataTypes.INTEGER(10),
},
minStockQuantity: {
type: DataTypes.INTEGER(10),
},
isComposite: {
type: DataTypes.INTEGER(1),
},
isAllowedOutOfStockSale: {
type: DataTypes.INTEGER(1),
defaultValue: '0'
},
isActive: {
type: DataTypes.INTEGER(1),
defaultValue: '0'
},
isDeceptive: {
type: DataTypes.INTEGER(1),
defaultValue: '0'
},
createdAt: {
type: DataTypes.DATE,
},
createdBy: {
type: DataTypes.INTEGER(10).UNSIGNED,
references: {
model: 'user',
key: 'id'
}
},
deletedAt: {
type: DataTypes.DATE,
},
deletedBy: {
type: DataTypes.INTEGER(10).UNSIGNED,
references: {
model: 'user',
key: 'id'
}
},
updatedAt: {
type: DataTypes.DATE,
},
updatedBy: {
type: DataTypes.INTEGER(10).UNSIGNED,
references: {
model: 'user',
key: 'id'
}
}
}, {
tableName: 'product',
timestamps: false,
defaultScope: {
where: {
isActive: true,
deletedAt: null,
}
}
});
// Association
product.associate = function(models) {
models.product.belongsTo(models.user);
models.product.belongsTo(models.user);
models.product.belongsTo(models.user);
models.product.belongsTo(models.product_category);
models.product.hasMany(models.product_composition);
};
return product;
}
This is my model implementation
models.findAll({})
.then(data => {
console.log(data)
.catch(err => {
console.log(err)
});
I am getting SequelizeDatabaseError. After investigation I trace out the generated query
SELECT `id`, `name`, `code`, `desc`, `productCategoryId`, `costPrice`, `sellPrice`, `markup`, `markupType`, `imgAttachment`, `minOrderQuantity`, `minStockQuantity`, `isComposite`, `isAllowedOutOfStockSale`, `isActive`, `isDeceptive`, `createdAt`, `createdBy`, `deletedAt`, `deletedBy`, `updatedAt`, `updatedBy`, `userId` FROM `product` AS `product` WHERE `product`.`id` = 1 AND `product`.`isActive` = 1 AND `product`.`deletedAt` IS NULL;
Why it is adding userId in query. This query works fine when I remove userId field from this generated query

That is because of this line :
This line will add a userId attribute to product to hold the primary key value for Product
models.product.belongsTo(models.user);
But This will not add the field , reason is , naming convention is followed for foreign key name productCategoryId but not in above case ,
models.product.belongsTo(models.product_category);
for that you should define that explicitly and you should also add alias name for association coz you are using one table for 3 relations , like
models.product.belongsTo(models.user , { as : 'delete_by' ,foreignKey: 'deletedBy'} );
models.product.belongsTo(models.user , { as : 'created_by' ,foreignKey: 'createdBy'} );
models.product.belongsTo(models.user , { as : 'updated_by' , foreignKey: 'updatedBy'} );
For more detail : DO READ

Related

multiple inner join at same table sequelize

I'm trying to make a query with multiple joins but when i execute it doesn't work says me
EagerLoadingError [SequelizeEagerLoadingError]: tbl_admon_brands is associated to tbl_admon_vehicles multiple times. To identify the correct association, you must use the 'as' keyword to specify the alias of the association you want to include
I was looking at the documentation of sequalize but i don't understand how can i make a polymorphic association with my models and controllers
Actually i have my getAll like this
const vehicles = await Vehicle.findAll({
attributes: {
include: [
[sequalize.col("brand.name"), "brandName"],
[sequalize.col("brandChassis.name"), "brandChassisName"],
[sequalize.col("brandEnginer.name"), "brandEnginerName"],
/* [sequalize.col("brandBodyWork.name"), "brandBodyWorkName"],
*/ [
sequalize.col("enginePosition.description"),
"enginePositionName",
],
],
},
include: [
{
model: Brand,
as: "brand",
attributes: [],
required: true,
},
{
model: Brand,
as: "brandChassis",
attributes: [],
required: true,
},
{
model: Brand,
as: "brandEnginer",
attributes: [],
required: true,
},
/*{
model: Brand,
as: "engine",
attributes: ['name'],
required: true,
},*/
{
model: Position,
as: "enginePosition",
attributes: [],
required: true,
},
],
where: {
deleted: 0,
},
logging: console.log
});
but when i unomment the line 7 and/or the as engine is when throw me the error.
My model
const { Sequelize } = require("sequelize");
const sequalize = require("../database/database");
const Models = require("./Models");
const Brand = require("./Brand");
const Position = require("./Position");
const Engines = require("./Engines");
const Vehicle = sequalize.define("tbl_admon_vehicles", {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
},
name: {
type: Sequelize.TEXT,
},
cut: {
type: Sequelize.TEXT,
},
vin: {
type: Sequelize.TEXT,
},
numberEconomic: {
type: Sequelize.TEXT,
},
unitNumber: {
type: Sequelize.INTEGER,
},
brandId: {
type: Sequelize.INTEGER,
},
modelId: {
type: Sequelize.INTEGER,
},
date_acquisition: {
type: Sequelize.DATE,
},
deleted: {
type: Sequelize.INTEGER,
},
brandidchassis: {
type: Sequelize.INTEGER,
},
brandidenginer: {
type: Sequelize.INTEGER,
},
brandidbodywork: {
type: Sequelize.INTEGER,
},
enginepositionid: {
type: Sequelize.INTEGER,
},
typefuelid: {
type: Sequelize.INTEGER,
},
stateplate: {
type: Sequelize.TEXT,
},
federalplate: {
type: Sequelize.TEXT,
},
serie: {
type: Sequelize.TEXT,
},
endorsement: {
type: Sequelize.DATE,
},
unitNumber: {
type: Sequelize.INTEGER,
},
clasificationId: {
type: Sequelize.INTEGER,
},
section: {
type: Sequelize.TEXT,
},
insurerid: {
type: Sequelize.INTEGER,
},
policy: {
type: Sequelize.INTEGER,
},
expedition: {
type: Sequelize.DATE,
},
expiration: {
type: Sequelize.DATE,
},
});
Vehicle.belongsTo(Models, {
foreignKey: "modelId",
as: "model",
});
Vehicle.belongsTo(Brand, {
foreignKey: "brandId",
as: "brand",
});
Vehicle.belongsTo(Brand, {
foreignKey: "brandidchassis",
as: "brandChassis",
});
Vehicle.belongsTo(Brand, {
foreignKey: "brandidenginer",
as: "brandEnginer",
});
Vehicle.belongsTo(Engines, {
foreignKey: "brandidbodywork",
as: "engine",
});
Vehicle.belongsTo(Position, {
foreignKey: "enginepositionid",
as: "enginePosition",
});
module.exports = Vehicle;
my query that i'm trying to do is
SELECT "tbl_admon_vehicles"."id", "tbl_admon_vehicles"."name",
"tbl_admon_vehicles"."cut", "tbl_admon_vehicles"."vin",
"tbl_admon_vehicles"."numberEconomic", "tbl_admon_vehicles"."unitNumber",
"tbl_admon_vehicles"."brandId", "tbl_admon_vehicles"."modelId",
"tbl_admon_vehicles"."date_acquisition", "tbl_admon_vehicles"."deleted",
"tbl_admon_vehicles"."brandidchassis", "tbl_admon_vehicles"."brandidenginer",
"tbl_admon_vehicles"."brandidbodywork", "tbl_admon_vehicles"."enginepositionid",
"tbl_admon_vehicles"."typefuelid", "tbl_admon_vehicles"."stateplate",
"tbl_admon_vehicles"."federalplate", "tbl_admon_vehicles"."serie",
"tbl_admon_vehicles"."endorsement", "tbl_admon_vehicles"."clasificationId",
"tbl_admon_vehicles"."section", "tbl_admon_vehicles"."insurerid",
"tbl_admon_vehicles"."policy", "tbl_admon_vehicles"."expedition",
"tbl_admon_vehicles"."expiration", "tbl_admon_vehicles"."createdAt",
"tbl_admon_vehicles"."updatedAt", "brand"."name" AS "brandName",
"brandChassis"."name" AS "brandChassisName", "brandEnginer"."name"
AS "brandEnginerName", "enginePosition"."description" AS "enginePositionName"
FROM "tbl_admon_vehicles" AS "tbl_admon_vehicles"
INNER JOIN "tbl_admon_brands" AS "brand" ON "tbl_admon_vehicles"."brandId" = "brand"."id"
INNER JOIN "tbl_admon_brands" AS "brandChassis"
ON "tbl_admon_vehicles"."brandidchassis" = "brandChassis"."id"
INNER JOIN "tbl_admon_brands" AS "brandEnginer"
ON "tbl_admon_vehicles"."brandidenginer" = "brandEnginer"."id"
INNER JOIN "tbl_admon_brands" AS "engine"
ON "tbl_admon_vehicles"."brandidbodywork" = "engine"."id"
LEFT OUTER JOIN "tbl_admon_engine_positions" AS "enginePosition"
ON "tbl_admon_vehicles"."enginepositionid" = "enginePosition"."id"
WHERE "tbl_admon_vehicles"."deleted" = 0
I hope someone can helpe or explain me how can i make the polymorphic association

Sequelize many to many "degree is not associated to doctor"

I have two models Doctor and Degree with many to many relationship.
Doctor model:
const Doctor = _sequelize.define('doctor', {
fullname: {
type: Sequelize.STRING,
allowNull: false
},
email: {
type: Sequelize.STRING,
allowNull: false
},
password: {
type: Sequelize.STRING,
allowNull: false
},
gender: {
type: Sequelize.STRING
},
address: {
type: Sequelize.STRING
},
phone: {
type: Sequelize.STRING
},
avatarurl: {
type: Sequelize.STRING
},
active: {
type: Sequelize.BOOLEAN,
defaultValue: true
},
license: {
type: Sequelize.STRING
}
},{
timestamps: false,
tableName: 'doctor'
})
Doctor.associate = (models) => {
Doctor.belongsToMany(model.degree, { through: 'doctor_degree', foreignKey: 'doctor_id',as: 'degree' })
}
Degree model:
const Degree = _sequelize.define('degree', {
name: {
type: Sequelize.STRING
}
},{
timestamps: false,
tableName: 'degree'
})
Degree.associate = (models) => {
Degree.belongsToMany(models.doctor, { through: 'doctor_degree', foreignKey: 'degree_id' })
};
Doctor_Degree model:
const Doctor_Degree = _sequelize.define('doctor_degree', {
doctor_id: {
type: Sequelize.STRING,
allowNull: false,
references: {
model: 'doctor',
key: 'id'
}
},
degree_id: {
type: Sequelize.STRING,
allowNull: false,
references: {
model: 'degree',
key: 'id'
}
}
},{
timestamps: false,
tableName: 'doctor_degree'
});
And I have a service to find all doctor with degree
var result;
try{
await doctorModel.findAll({
attributes: ['id','fullname', 'email','gender','address','phone','avatarurl','active','license'],
include: [{
model: degreeModel,
as: 'degree'
}]
}).then((doctors) => {
result = doctors
})
}
catch(err){
throw err
}
return result
But i got the following error:
[SequelizeEagerLoadingError]: degree is not associated to doctor!
Can anyone suggest what I am doing wrong?

How can I use current query value in sequelize?

I am new with sequelize and i need to include multiple table, i try belove:
const result = await product.findAll({
where: {
isDeleted: false,
sellerId
},
attributes: ["name", "type", "isActive", "subCategoryIds"],
include: [
{
model: category,
as: 'categories',
attributes: ["name"],
},
{
model: category,
as: 'subCategories',
attributes: ["name"],
where: {
id: _.split(sequelize.col("subCategoryIds"), ",")
},
},
],
offset: (page - 1) * limit,
limit
});
But it's return error :
SequelizeDatabaseError: operator does not exist: character varying = integer
Product model is:
const product = sequelize.define("products",
{
id: {
type: DataTypes.BIGINT.UNSIGNED,
field: "id",
primaryKey: true,
autoIncrement: true,
index: true,
},
name: {
type: DataTypes.STRING,
field: "name",
allowNull: false,
},
type: {
type: DataTypes.STRING,
field: "type",
allowNull: false,
},
categoryId: {
type: DataTypes.NUMBER,
field: "categoryId",
references: {
key: "id",
model: category,
},
allowNull: false,
},
sellerId: {
type: DataTypes.NUMBER,
field: "sellerId",
references: {
key: "id",
model: user,
},
allowNull: false,
},
subCategoryIds: {
type: DataTypes.STRING,
allowNull: false,
get() {
const result = _.split(this.getDataValue("subCategoryIds"), ",").map(item => +item);
return result;
}
},
isDeleted: {
type: DataTypes.BOOLEAN,
field: "isDeleted",
defaultValue: false,
},
createdAt: {
type: DataTypes.DATE,
field: "createdAt",
defaultValue: DataTypes.NOW,
},
updatedAt: {
type: DataTypes.DATE,
field: "updatedAt",
defaultValue: DataTypes.NOW,
}
}, {
tableName: "products",
timestamps: false
}
);
product.belongsTo(category, { as: "categories", foreignKey: 'categoryId' });
category.hasMany(product, { as: "products", foreignKey: 'categoryId' });
product.belongsTo(category, { as: "subCategories", foreignKey: 'subCategoryIds' });
I am not getting what's going wrong
is there any solution for this
details in table like
categoryId => 11 subCategoryIds => 11, 12
if i remove
{
model: category,
as: 'subCategories',
attributes: ["name"],
where: {
id: _.split(sequelize.col("subCategoryIds"), ",")
},
},
then it's working fine, problem is sequelize.col("subCategoryIds") return string col("subCategoryIds") not the actual value of the subCategories ids 11, 12

Sequelize simple inner join

I have two models, policyTable and policy_rule defined as below. There is a column called policy_id in policy_rule which is a foreign key and references to id column in policyTable. The policy_rule can have multiple policyTable, i.e there is a 1:N relationship.
var policyTable = dbController.db.define('policyTable', {
id: {
type: Sequelize.BIGINT,
autoIncrement: true,
primaryKey: true
},
't': {
type: Sequelize.BIGINT,
unique: true
},
'name': {
type: Sequelize.STRING,
},
src: {
type: Sequelize.STRING
}
}, {
timestamps: false,
freezeTableName: true,
tableName: 'zo_policy',
});
var policy_rule = dbController.db.define('policy_rule', {
policy_id: {
type: Sequelize.BIGINT,
references: {
model: policyTable,
key: 'id'
},
onUpdate: 'cascade',
onDelete: 'cascade'
},
agent_id: {
type: Sequelize.BIGINT,
},
enabled: {
type: Sequelize.BOOLEAN,
}
}, {
timestamps: false,
freezeTableName: true,
tableName: 'zo_policy_rule',
});
Now I want to join these two models and get all columns of both of them. How can I do that? I tried the below code but it says
Error: policy_rule is not associated to policyTable!
function getAllPolicies() {
return policyTable.findAndCountAll({
include: [{
model: policy_rule
}]
}).then(function (users) {
console.log(users);
data.count = users.count;
data.users = users.rows;
console.log(data);
return data;
});
};
Even though your associations are defined at the database level, and you indicate this in your column definitions, to use sequelize's include feature, you still need to explicitly define your associations between models, too.
Here's the relevant section in the doco: http://docs.sequelizejs.com/en/latest/docs/associations/#belongsto
and
http://docs.sequelizejs.com/en/latest/docs/associations/#1m
In your case, it'll mean adjusting your code to something along the lines of below - note the new classMethods section in each model definition:
var policyTable = dbController.db.define('policyTable', {
id: {
type: Sequelize.BIGINT,
autoIncrement: true,
primaryKey: true
},
't': {
type: Sequelize.BIGINT,
unique: true
},
'name': {
type: Sequelize.STRING,
},
src: {
type: Sequelize.STRING
}
}, {
timestamps: false,
freezeTableName: true,
tableName: 'zo_policy',
classMethods: {
associate(models) {
this.hasMany(models.policy_rule, {foreignKey: 'policy_id'})
}
}
});
var policy_rule = dbController.db.define('policy_rule', {
policy_id: {
type: Sequelize.BIGINT,
references: {
model: policyTable,
key: 'id'
},
onUpdate: 'cascade',
onDelete: 'cascade'
},
agent_id: {
type: Sequelize.BIGINT,
},
enabled: {
type: Sequelize.BOOLEAN,
}
}, {
timestamps: false,
freezeTableName: true,
tableName: 'zo_policy_rule',
classMethods: {
associate(models) {
this.belongsTo(models.policyTable, {foreignKey: 'policy_id'})
}
}
});

Want to output ID value of user and display it on console

I am using a sailsjs framework for an app. I am building, and I am trying to extract the id value from a model I have:
const memoryCreatorId = _(Memory.creator).map('id').value();
console.log(memoryCreatorId);
const message = {
app_id: '***********************',
contents: {"en": "Yeah Buddy, Rolling Like a Big Shot!"},
filters: [{"field": "tag", "key": "userId", "relation": "=", "value": memoryCreatorId}],
ios_badgeType: 'Increase',
ios_badgeCount: 1
};
return PushNotificationService.sendNotification(message);
I'm basically trying to get what would be the Memory.creator.User.id value. So basically the userid of the person who creates a memory. I'm trying to get it from the "Memory" model "creator" attribute, which maps to the "User" model, and from the "User" model, extract the "id" attribute. Thanks for your help in advance!
Memory model below:
Memory.js
const _ = require('lodash');
module.exports = {
attributes: {
creator: {
model: 'User'
},
title: {
type: 'string'
},
description: {
type: 'text'
},
contentUrl: {
type: 'string',
url: true
},
cropRect: {
type: 'string'
},
likers: {
collection: 'User',
via: 'memoryLikes'
},
comments: {
collection: 'Comment',
via: 'memory'
},
update: {
model: 'Update',
},
cause: {
model: 'Cause',
}
}
};
User model is a follows:
User.js
'use strict';
const uuid = require('node-uuid');
const CipherService = require('../services/CipherService');
const BraintreeService = require('../services/BraintreeService');
module.exports = {
attributes: {
id: {
type: 'string',
primaryKey: true,
defaultsTo: () => uuid.v4(),
unique: true,
index: true,
uuidv4: true
},
firstName: {
type: 'string',
defaultsTo: ''
},
lastName: {
type: 'string',
defaultsTo: ''
},
email: {
type: 'string',
email: true,
required: true,
unique: true
},
password: {
type: 'string'
},
passwordResetToken: {
type: 'string'
},
passwordResetTokenExpires: {
type: 'string'
},
type: {
type: 'string',
enum: ['admin', 'member']
},
city: {
type: 'string'
},
state: {
type: 'string'
},
address: {
type: 'string'
},
institution: {
model: 'Institution'
},
major: {
type: 'string'
},
contentUrl: {
type: 'string',
url: true,
defaultsTo: AwsService.getAssetImageUrl('user-default.png')
},
cropRect: {
type: 'string'
},
graduationYear: {
type: 'integer'
},
donations: {
collection: 'Donation',
via: 'donor'
},
memories: {
collection: 'Memory',
via: 'creator'
},
causes: {
collection: 'Cause',
via: 'followers',
dominant: true
},
adminCauses: {
collection: 'Cause',
via: 'admins'
},
isLeader: {
type: 'boolean',
defaultsTo: false
},
isCurrentStudent: {
type: 'boolean',
defaultsTo: false
},
isAdmin: {
type: 'boolean',
defaultsTo: false
},
adminTitle: {
type: 'string'
},
paymentProfile: {
model: 'PaymentProfile'
},
jsonWebTokens: {
collection: 'Jwt',
via: 'owner'
},
memoryLikes: {
collection: 'Memory',
via: 'likers'
},
updateLikes: {
collection: 'Update',
via: 'likers'
},
toJSON: function() {
return User.clean(this);
}
},
beforeUpdate: (values, next) => {
CipherService.hashPassword(values).then(() => next()).catch(next);
},
beforeCreate: (values, next) => {
CipherService.hashPassword(values).then(() => next()).catch(next);
},
clean: (user) => {
//let obj = user.toObject();
delete user.password;
delete user.jsonWebTokens;
delete user.passwordResetToken;
delete user.passwordResetTokenExpires;
return user;
}
};

Resources