I have red the documentation of sequelize but could not get the idea/concept i wanted ,I don't want just one attribute to be shown.
We have the following syntax to get the attributes we need
Model.findAll({
attributes:['foo','bar]
})
In my case I have many attributes in single table , I just want to hide one attribute.Is there any way in sequelize that we define the attribute which we don't want to see and get all other by default..
For Example....
Model.findAll({
attributes:hide foo , show all other attributes
})
AnyOne Can help..
You can use below syntax.
Model.findAll({
attributes: {
exclude: ['foo'] // hide this
}
});
You can also exclude fields on model level by adding in their default scope like below.
const Model = sequelize.define('model',{
secretColumn: Sequelize.STRING,
//... and other columns
}, {
defaultScope: {
attributes: { exclude: ['secretColumn'] }
}
});
Related
Whenever I do a findAll or findOne on a model and it involves nested association. All the property of the association also get nested. Like below :
ProductQCStatus.findAll({
include:[
{
model:Product,
include:{
model:ProductImage
},
attributes:["product_name","product_description","category"]
}
],
})
It will be below result
[{
//fields from ProductQCStatus table
Product:{
product_name: value
product_description: value,
...
ProductImage:{
images:[]
}
},
{
//fields from ProductQCStatus table
Product:{
product_name: value
product_description: value,
...
ProductImage:{
images:[]
}
}
......
]
I want the result not be nested but just one object with all the attributes defined inside nested associations.
I have already tried map(), also using other functions through which I can iterate and get the desired fields. But in that case, I have to traverse whole objects. I don't want that.I went through documentation, and I couldn't find anything there.
I wonder if there is any native method in sequelize itself to achieve this.
I have gone through the Sequelize doc, but can't find anything helpful
What I want to do is to add raw query or custom model in include, is it possible ?
model.Post.findAll({
include: [{
model: model.User,
attributes: ['fullname', 'profilepic'],
},
{
model: model.PostComments,
},
{
model: "Raw Query"
}
]
}
What I want to achieve is like :
Select post_id, count(*) as total_likes from post_likes group by post_id
I can't achieve this by using simply include, so what I want to do is create a table/model from above query and then use it inside include.
If I use group by withing include it gives group by from top level, and I want to apply group by just for the post_like table.
Please let me know, if it found confusing or not clear.
I was looking to do the same, use a raw query dynamically formed inside the include but there's no possible way to use include without a model https://sequelize.org/master/class/lib/model.js~Model.html#static-method-findAll .
For the purposes of my MySQL I turned my inner join (include) into a where in. I was doing the inner join to avoid the exception This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery . I get this exception because I have a subquery with LIMIT applied.
If it helps anyone:
let rows = await j_model.findAll({
attributes: [...j_columns, `${association}.meta_key_id`],
include: [
{
model: um_model,
as: association,
attributes: ['um_id'],
on: {'j_id' : {$col: 'j.j_id'} }
],
where: {'j_id': {$in: sequelize.literal(`(SELECT * FROM (${massive_inner_raw_query}) as tmp)`)}},
logging: console.log
});
The actual magic is in this line:
where: {'j_id': {$in: sequelize.literal(`(SELECT * FROM (${massive_inner_raw_query}) as tmp)`)}}
The SELECT * FROM removes that exception and lets me do a where in instead of the wanted INNER JOIN. Maybe you can apply a similar deal to your problem.
You can use
Model.findAll({
attributes: [[models.sequelize.literal('CASE WHEN "field1" = true THEN 55
ELSE 23 END'), 'field3']]
}
OR
Model.findAll({
attributes: { include: [[models.sequelize.literal('CASE WHEN "field1" = true THEN 55 ELSE 23 END'), 'field3']]}
}
How to remove some fields of model from find* (Like password, token)?
I think overriding toJSON() function (Like here https://stackoverflow.com/a/27979695/6119618) is not a good way, because i sometimes need this field for password validation or token for checking etc..
Is there something like as .select('+token') as mongoose has?
And another question i think it's fit this topic.
How to remove generated by through fields from find* output?
When i call User.find() it responds { id: 0, name: 'somename', UserProjectsTie: { /* complex object of many-to-many relation table */ } }
To exclude an attribute from find*:
Model.findAll({
attributes: { exclude: ['baz'] }
});
To make this the default behavior, use a scope:
const Model = sequelize.define('Model', {
// Attributes
}, {
defaultScope: {
attributes: { exclude: ['baz'] }
}
});
Unless I'm mistaken the 'through' should only show up when using 'include'. To get rid of through in that case:
Model.findAll({
include: [{association: 'OtherModels', through: {attributes: []}}]
});
So I have model Alarms which is associated with Site model and others... Is it possible somehow set that by default when are required Alarm.findAll().then() I didn’t need to specify which associated models I need? It is necessary because Alarms table are using in many different situations and some different apps but in my case I need only entries which has site.
Or may be somehow I can add default joins to the model?
Usually when I encounter situations like this, I would just make a module which returns a promise of the query (with joins). So, for example you could make an alarm_util module
exports.getAlarm = function() {
return Alarms.findAll({
include: [{
model: Site,
include: [{
model: OtherModel
}]
}]
});
};
module.exports = exports;
And use it anywhere in your code like
alarm_util.getAlarm().then(alarm => {
// The rest of your logic here...
});
We need to have sequelize return dates in a particular format, not the default one. As far as I can tell, there is no way to set that up in options, or any other way. Short of manually updating the dates every time after they are retrieved, anyone been able to solve this easily? Or am I missing something?
You can, use the Sequelize fn method. From the API Reference, the fn function will help create an object representing a SQL function in your query.
For example:
model.findAll({
attributes: [
'id',
[sequelize.fn('date_format', sequelize.col('date_col'), '%Y-%m-%d'), 'date_col_formed']
]})
.then(function(result) {
console.log(result);
});
Will return data values:
[
{"id": 1, "date_col_formed": "2014-01-01"},
{"id": 2, "date_col_formed": "2014-01-02"}
// and so on...
]
21/06/2019
A little bit late but providing an update.
Sequelize is a powerful ORM (I am not saying is the best solution out there) but has a very bad documentation.
Anyway if you want to have this configured in your models one way apart from having to repeat this across your queries as other responses state you could be doing:
const Test = sequelize.define('test', {
// attributes
name: {
type: DataType.STRING,
allowNull: false
},
createdAt: {
type: DataType.DATE,
//note here this is the guy that you are looking for
get() {
return moment(this.getDataValue('createdAt')).format('DD/MM/YYYY h:mm:ss');
}
},
updatedAt: {
type: DataType.DATE,
get() {
return moment(this.getDataValue('updatedAt')).format('DD/MM/YYYY h:mm:ss');
}
}
If you are using dates to provide info as: last updated, first login, last login. This is the way to go.
The function get returns the new formatted element so it should not be restricted to dates either! Just bear in mind that this will slow your query so use cautiously. ;)
more info (i know i know but docs is the name of the game): https://sequelize.org/docs/v6/core-concepts/getters-setters-virtuals/
you can define custom instance methods getDate/setDate which would translate date between sequelize internal representation and desired format like so https://sequelize.org/master/manual/model-basics.html#taking-advantage-of-models-being-classes
If you are wondering to cast it as VARCHAR :
attributes:{include:[[sequelize.cast(sequelize.col('dob'), 'VARCHAR') , 'dob']],exclude:['dob']}
In case of Model that we create using Sequelize CLI
try something like this
var sequelize= require('../models');
model.findAll({
attributes: [
'id',
'title'
[sequelize.Sequelize.fn('date_format', sequelize.Sequelize.col('col_name'), '%d %b %y'), 'col_name']
]}.then(function(result))
{ // dateformate=04 Nov 2017
console.log(result)
}
visit this link for formate
To format Date, you can use Sequelize.fn method. I tried all mentioned methods but it won't work with date_formate. Try to create with bellow one.
model.findAll({
attributes: [
'id',
[sequelize.fn('FORMAT', sequelize.col('col_name'), 'yyyy-mm-dd'), 'col_name']
]})
.then(function(result) {
console.log(result);
});
here, i used 'FORMAT' instead of 'DATE_FORMAT', because it through error :
'date_format' is not a recognized built-in function name in api call.
For me, date_format and Format functions in above answers do not work.
I solved as below:
attributes: [
[sequelize.literal('date("dateTime")'), 'dateWithoutTime'],
],