Eager Loading : How to disable specific fields of included table - postgresql

I am trying to do Eager Loading in Sequelize with PostgreSQL where I need to find the Users which have a given specific Mail id or basically, i am performing find operation on Mail model while using include to include User model
UserModel :
module.exports = function (sequelize, Sequelize) {
var User = sequelize.define('User', {
userId: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
},
firstname: {
type: Sequelize.STRING,
require: true
},
lastname: {
type: Sequelize.STRING,
require: true
},
age: {
type: Sequelize.INTEGER,
require: true
},
phone: {
type: Sequelize.STRING,
require: true
},
location: {
type: Sequelize.STRING,
require: true
},
createdAt: {
type: Sequelize.DATE,
defaultValue: Sequelize.NOW
},
updatedAt: {
type: Sequelize.DATE,
defaultValue: Sequelize.NOW
}
});
return User;
};
MailModel :
module.exports = function (sequelize, Sequelize) {
var User = require('./User.js')(sequelize, Sequelize)
var Mail = sequelize.define('Mail', {
name: {
type: Sequelize.STRING,
require: true
}
});
Mail.belongsTo(User);
return Mail;
};
MailController :
var db = require('../services/db.js');
module.exports = {
create: function (req, res, next) {
var Mailm = db.MailModel;
var name = req.body;
try {
db.sequelize.sync().then(function () {
Mailm.create(name).then(function (found) {
return res.json({
success: true,
message: found.get({
plain: true
})
});
})
});
} catch (ex) {
res.json({
success: false,
exception: ex
});
return;
}
},
query: function (req, res, next) {
var Mailm = db.MailModel;
var Userm = db.UserModel;
var name = req.body;
var option = {};
option.where = name;
option.include = [{
model: Userm
}];
try {
Mailm.findAll(option).then(function (found) {
console.log(found);
return res.json({
success: true,
message: found
});
});
} catch (ex) {
res.json({
success: false,
exception: ex
});
return;
}
}
};
It is returning me the records of both User and Mail table in exactly the right way .
Output :
{
"success": true,
"message":[
{
"id": 2,
"name": "Mailb2",
"createdAt": "2015-07-30T07:32:51.807Z",
"updatedAt": "2015-07-30T07:32:51.807Z",
"UserUserId": 2,
"User":{
"userId": 2,
"firstname": "Prerna",
"lastname": "Jain",
"age": 20,
"phone": "9812123456",
"location": "Sirsa",
"createdAt": "2015-07-30T07:30:48.000Z",
"updatedAt": "2015-07-30T07:30:48.000Z"
}
}
]
}
But I want to disable createdAt and updatedAt fields of User table so that it does not give me these two fields in the output for User.
I have tried a lot as of how to do this but still in vain.Can anyone please help me out.

I bet this is coming late, add attribute/properties to your models called timestamps, it accepts a boolean as a value. For example:
module.exports = function (sequelize, Sequelize) {
var User = require('./User.js')(sequelize, Sequelize)
var Mail = sequelize.define('Mail', {
name: {
type: Sequelize.STRING,
require: true
}
},
{
// This does the magic
timestamps: false,
});
Mail.belongsTo(User);
return Mail;
};
Also, add it to the User model:
var User = sequelize.define('User', {
userId: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
},
firstname: {
type: Sequelize.STRING,
require: true
},
lastname: {
type: Sequelize.STRING,
require: true
},
age: {
type: Sequelize.INTEGER,
require: true
},
phone: {
type: Sequelize.STRING,
require: true
},
location: {
type: Sequelize.STRING,
require: true
},
createdAt: {
type: Sequelize.DATE,
defaultValue: Sequelize.NOW
},
updatedAt: {
type: Sequelize.DATE,
defaultValue: Sequelize.NOW
}
},
{
timestamps: false
});
return User;
};

You can use
Model.findAll({
attributes: { exclude: ['baz'] }
});
more examples with attributes - http://docs.sequelizejs.com/en/latest/docs/querying/#attributes

Related

How to set common where param to all models in query, in sequelize

I'm trying to realize the query, where I can find all records, which at least one of the attributes includes the text, user send with request, for that I use where, but it can search, as I understand, in only own model, but i need it to search it in parent model and in associated filds together, not apart.
There is my models:
const Picture = sequelize.define<IPictureInstance>('picture', {
id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
img: { type: DataTypes.STRING, allowNull: false },
mainTitle: { type: DataTypes.STRING, allowNull: false },
description: { type: DataTypes.TEXT }
});
const PictureInfo = sequelize.define<IPictureInfoInstance>('pictureInfo', {
id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
title: { type: DataTypes.STRING, allowNull: false },
description: { type: DataTypes.STRING, allowNull: false }
});
const PictureTag = sequelize.define<IPictureTagInstance>('pictureTag', {
id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
text: { type: DataTypes.TEXT, allowNull: false }
});
const PicturesTags = sequelize.define<IPicturesTagsInstance>('picturesTags', {
id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true }
});
And their associations:
Picture.belongsToMany(PictureTag, { through: PicturesTags, as: "tags", onDelete: 'cascade' });
PictureTag.belongsToMany(Picture, { through: PicturesTags, as: "pictures", onDelete: 'cascade'
});
Picture.hasMany(PictureInfo, { onDelete: "cascade" });
PictureInfo.belongsTo(Picture);
That's what I tried to do:
static async getPictures(query: string | undefined) {
const pictures = await models.Picture.findAll({
where: {
[Op.or]: {
mainTitle: { [Op.iRegexp]: `${query}` },
description: { [Op.iRegexp]: `${query}` },
},
},
include: [
{
model: models.PictureInfo,
as: "pictureInfos",
where: {
[Op.or]: {
title: { [Op.iRegexp]: `${query}` },
description: { [Op.iRegexp]: `${query}` }
}
},
required: false
},
{
model: models.PictureTag,
as: "tags",
attributes: ["id", "text"],
where: { text: { [Op.iRegexp]: `${query}` } },
through: {
attributes: [],
},
required: false
}
],
});
return pictures;
}
But in this case, when it can't find records in first where param it returns an empty array, I understand it, but it isn't a behavior I need.
I need to check every attribute together.
So, if user send query=cat, it will check mainTitle and description, if there is nothing, it will check associated pictureInfos fields and after, if there is nothing, check pictureTags associated fields, that's what I need, will be grateful for the help.
My solution:
static async getPictures(query: string | undefined) {
const whereStatement = {
[Op.or]: {
mainTitle: { [Op.iRegexp]: `${query}` },
description: { [Op.iRegexp]: `${query}` },
"$tags.text$": { [Op.iRegexp]: `${query}` },
"$pictureInfos.title$": { [Op.iRegexp]: `${query}` },
"$pictureInfos.description$": { [Op.iRegexp]: `${query}` },
}
};
const pictures = await models.Picture.findAll({
where: whereStatement,
include: [
{
model: models.PictureInfo,
as: "pictureInfos",
},
{
model: models.PictureTag,
as: "tags",
}
],
});
return pictures;
}
But I'm still confused with those $ symbols, what they are for, I couldn't find the answer in documentation?
Link to the Sequelize documentation, to confirm my answer

Sequelize Model associations - foreign key missing

I have 2 models that I am associating like this. Customer is associated to application by 1:M relationship.
customer:
'use strict';
module.exports = (sequelize, DataTypes) => {
let customer = sequelize.define('customer', {
id: {
type: DataTypes.INTEGER,
allowNull: false,
primaryKey: true,
autoIncrement: true
},
name: {
type: DataTypes.STRING
},
account_id: {
type: DataTypes.STRING
},
code: {
type: DataTypes.STRING
},
createdAt: {
type: DataTypes.DATE,
defaultValue: sequelize.literal('NOW()')
},
updatedAt: {
type: DataTypes.DATE,
defaultValue: sequelize.literal('NOW()')
}
},
{
underscored: true,
freezeTableName: true,
tableName: 'customer'
});
customer.associate = function(models) {
// associations can be defined here
customer.hasMany(models.application, { foreignKey:
'customer_id' });
};
sequelize.sync()
.then(() => customer.create(
{ name: "customer1", account_id: "cust-1-acct-1", code: "ACME Inc." }
)).then(function(customer) {
console.log('customers created');
}).then(() => customer.create(
{ name: "customer2", account_id: "cust-2-acct-2", code: "test Cust" }
)).then(function(customer) {
console.log('customers created');
})
.catch(function(err) {
console.log(err);
});
return customer;
}
application:
'use strict';
module.exports = (sequelize, DataTypes) => {
let application = sequelize.define('application', {
id: {
type: DataTypes.INTEGER,
allowNull: false,
primaryKey: true,
autoIncrement: true
},
name: {
type: DataTypes.STRING,
sortable: true
},
creation_date: {
type: DataTypes.NUMERIC,
sortable: true
},
customer_id: {
type: DataTypes.INTEGER
},
createdAt: {
type: DataTypes.DATE,
defaultValue: sequelize.literal('NOW()')
},
updatedAt: {
type: DataTypes.DATE,
defaultValue: sequelize.literal('NOW()')
}
},
{
underscored: true,
freezeTableName: true,
tableName: 'application'
});
application.associate = function(models) {
// associations can be defined here
application.belongsTo(models.customerView, { through: 'customer_id' });
};
sequelize.sync()
.then(() => application.create(
{ customer_id: "1", name: "application 1", creation_date: "1556724178700" }
)).then(() => application.create(
{ customer_id: "1", name: "application 2", creation_date: "1556724178700" }
)).then(() => application.create(
{ customer_id: "2", name: "application 3", creation_date: "1556724178700" }
))
.then(function(application) {
console.log('applications created');
})
.catch(function(err) {
console.log(err);
});
return application;
}
These 2 tables are getting created as expected, but without the foreign key constraint that I am expecting. The foreign key should be on the application table, on customer_id.
What am I doing wrong?

How can I overwrite the entire document, instead of just updating the fields?

How can I overwrite the entire document, instead of just updating the fields?
Here is the method I use right now but doesn't work:
updateFilmTitle: function(req, res) {
var id = req.params.id;
console.log(id);
filmTitleModel.findByIdAndUpdate(id, req.body, {
overwrite: true
}, {
new: true
}, (error, response) => {
if (error) {
res.json(error);
console.error(error);
return;
}
console.log("filmTitle form has been updated!");
res.json(response);
console.log(response);
});
},
here how my model looks like,
var venueSchema = new Schema({
ticketServiceRequired: { type: Boolean, required: true },
filmSettings: {
type: {
filmContactName: { type: String, required: true },
filmSeatingAmount: { type: Number, required: true },
filmMediaDelivery: { type: Array, required: true },
filmRentalFee: {
price: { type: Number, required: true },
type: { type: String, required: true },
},
}
},
});
new and overwrite both are options, so it should be this:
filmTitleModel.findByIdAndUpdate(id, req.body, {
overwrite : true,
new : true
}, (error, response) => { ... });

sails update the doc, nothing happen, not err message

eventController:
newHelper: function(req, res) {
const eventID = req.body.eventID;
let newHelper = req.body.newHelper;
newHelper.eventAssoc = eventID;
Wapphelprecords.create(newHelper).exec(function(err, newhelper) {
if (err) {
return res.serverError(err); }
sails.log('add new helper:', newhelper);
return res.json(newhelper);
});
}
when I do this action, the database nothing happen, and no err message, this is model under blow:
WappeventController model:
module.exports = {
attributes: {
eventID: {
type: 'integer',
// autoIncrement: true,
unique: true,
// defaultsTo: 0
},
openid: {
type: 'string',
},
author: {
model: 'wappuserinfo'
},
content: {
type: 'string'
},
allowShare: {
type: 'boolean'
},
imageList: {
type: 'array'
},
money: {
type: 'float',
},
helpers: {
collection: 'wapphelprecords',
via: 'eventAssoc',
},
bestHelper: {
collection: 'wapphelprecords',
via: 'eventAssoc',
}
},
Wapphelprecords Model:
module.exports = {
attributes: {
eventAssoc: {
model: 'wappevents',
},
content: {
type: 'string'
},
contact: {
type: 'string'
},
userInfo: {
model: 'wappuserinfo'
},
bestHelper: {
type: 'boolean'
},
moneyEarn: {
type: 'float'
}
}
};
when I do newHelper action, the database nothing happened, and nothing error notice, I just do not understand. need help, thx.
spend whole day to fix it, and finally:
module.exports = {
attributes: {
eventID: {
type: 'integer',
// autoIncrement: true,
primaryKey: true, //<---- set this primarkey to true
unique: true,
// defaultsTo: 0
},
openid: {
type: 'string',
},
author: {
model: 'wappuserinfo'
},
content: {
type: 'string'
},
allowShare: {
type: 'boolean'
},
imageList: {
type: 'array'
},
money: {
type: 'float',
},
helpers: {
collection: 'wapphelprecords',
via: 'eventAssoc',
},
bestHelper: {
collection: 'wapphelprecords',
via: 'eventAssoc',
}
},

Getting "model is not associated with other Model" in sequelize when using belongsToMany

I am using sequelize with postgreSQL. I have two schemas namely User and Location. A User can have many Locations and a Location can have many Users.
My User Schema is as follows
id: {
type: Sequelize.INTEGER,
autoIncrement: true,
primaryKey: true
},
firstName: {
type: Sequelize.STRING,
require: true
},
middleName: {
type: Sequelize.STRING,
require: false
},
lastName: {
type: Sequelize.STRING,
require: true
},
age: {
type: Sequelize.INTEGER,
require: false
},
email_Id: {
type: Sequelize.STRING,
require: true,
unique: true,
validate: {
isEmail: true
}
}
My Location Schema is as follows:
id: {
type: Sequelize.INTEGER,
autoIncrement: true,
primaryKey: true
},
latitude: {
type: Sequelize.DOUBLE,
require: true
},
longitude: {
type: Sequelize.DOUBLE,
require: true
},
locationAddress: {
type: Sequelize.STRING
},
mailBoxNo: {
type: Sequelize.INTEGER
}
I Am using belongsToMany of sequelize and creating a third table name UserLocation where I have mentioned belongsToMany for both User and Location which is as below:
User.belongsToMany(Location, {
through: 'UserLocation'
});
Location.belongsToMany(User, {
through: 'UserLocation'
});
My requirement is to get all the locations for a given user id. My Code is as follows:
var param = req.body;
var options = {};
if (param.where) {
options.where = param.where;
}
options.include = [{
model: User //User Model
}, {
model: Location //Location Model
}];
//Here userLocation refers to UserLocation Schema
userLocation.findAll(options).then(function (response) {
//Some Logic
}).catch(function (err) {
//Error handling
});
While executing the above code, I getting the following error:
User Model is not associated with UserLocation Model.
I am unable to understand why I am getting the following error. Can somebody help me out with this?
You can use this for getting all the locations of a given user;
User
.findOne({
"where": {
"id": param.where
},
"include": [Location]
})
.then(function(user) {
// should get this user
console.log(user);
// should get all locations of this user
console.log(user.Locations);
})
.catch(function(error) {
// error handling
});