In Sequelize model.destroy({ truncate: true }) does not reset primary key - javascript

In Sequelize, I am using this function model.destory({ truncate: true }), it delete all data in table. But the issue is that it does not reset the primary key sequence in table which should be set to Zero. I am using Mysql.
Some said that Mysql automatically reset the primary key sequence, but it is not happening in my case.
Here is my code:
db.Booking.destroy({ truncate: { cascade: false } })
.then(() => {
res.json({ status: true });
}, (err) => {
console.log('truncate: ', err);
res.json(err);
});

You're not using the correct syntax:
db.Booking.destroy({ truncate: { cascade: false } })
That should be:
db.Booking.destroy({ truncate : true, cascade: false })
See the documentation.

if you are, in any case, using a custom foreign key, use this instead
db.Booking.truncate({cascade: true, restartIdentity:true})
as destroy would not work at will with custom foreign key
this one is nested pretty deep in the documentation
See here

Related

Can't update(nor save) existing row using Sequelize

When trying to .update() or .save() a row I'm getting this error:
Unhandled rejection Error: You attempted to save an instance with no primary key,
this is not allowed since it would result in a global update
I tried all 4 ways the docs uses as examples(with and without defining the attributes I wanna save), nothing worked.
This is my actual code for updating:
Sydney.databases.guilds.findOrCreate({
attributes: ['guildLocale'],
where: {
guildID: _guild.id,
},
defaults: {
guildID: _guild.id,
guildLocale: 'en_US',
guildPrefix: '?',
},
}).spread((guild, created) => {
guild.update({guildLocale: args[1]})
.then(() => console.log(7))
.catch((e) => throw e);
});
And this is the guild model:
let model = sequelize.define('guild', {
guildID: {
field: 'guild_id',
type: DataTypes.STRING,
primaryKey: true,
},
guildLocale: {
field: 'guild_locale',
type: DataTypes.STRING,
},
guildPrefix: {
field: 'guild_prefix',
type: DataTypes.STRING,
},
}, {tableName: 'guilds'});
What am I missing here?
I had the same problem. It occurs when you specify the attributes you want to fetch from the database without including the primary key in the attributes. And when you attempt to save, it will throw the following error:
Unhandled rejection Error: You attempted to save an instance with no primary key, this is not allowed since it would result in a global update
So the simple solution is to include the primary key in the attributes like this:
Sydney.databases.guilds.findOrCreate({
attributes: ['guildLocale', 'guildID'], // include guideID here!!
where: {
guildID: _guild.id,
},
defaults: {
guildID: _guild.id,
guildLocale: 'en_US',
guildPrefix: '?',
},
}).spread((guild, created) => {
guild.update({guildLocale: args[1]})
.then(() => console.log(7))
.catch((e) => throw e);
});
Ok, so the problem seems that was the attributes: ['guildLocale'] in the .findOrCreate() method. I can't tell why, to be honest, gonna read that doc again to be sure, but I'll leave this answer if another newbie is getting trouble with this, ;P...

MongoDb mongoose aggregatePagination returns multiple same documents over different pages

I am facing an issue with mongodb and mongoose with pagination.
I am trying to query over a set of Tutors and get those who are matching the query in a paginated and sorted (by updatedDate) result.
But the fact is I get multiple same documents over different pages ...
I would like it to return a set of unique documents.
Here is part of my function (the rest is just to build the query from the request body):
exports.search = (req, res) => {
var options = { page: page, limit: perPage, sortBy: { updatedDate: -1 }}
const aggregate = Tutor.aggregate([
{
"$geoNear":
{
"near":
{
"type": "Point",
"coordinates": [lon1, lat1]
},
"distanceField": "distance",
"spherical": true,
"maxDistance": radius
}
},
{
$match: match
}
]);
Tutor
.aggregatePaginate(aggregate, options, function (err, result, pageCount, count) {
if (err) {
return res.status(400).send(err);
}
else {
var opts = [
{ path: 'levels', select: 'name' },
{ path: 'subjects', select: 'name' },
{ path: 'assos', select: 'name' }
];
Tutor
.populate(result, opts)
.then(result2 => {
return res.send({
page: page,
perPage: perPage,
pageCount: pageCount,
documentCount: count,
tutors: result2
});
})
.catch(err => {
return res.status(400).send(err);
});
}
})
};
Now, imagine I am querying page 1 with a limit per page of 8. I 've got back my 8 documents correctly, all different. But when I am querying page 2, with the same limit per page, half of the documents were already returned in page 1 !
Would you know why is that so ? Thank you !
EDIT
I figured it was the sortBy that makes it happen. If i remove it, everything works correctly. I need it though ...
After doing alot of research. I found this solution. Hope it will solve your issue.
Jobs.aggregatePaginate(aggregateQuery, { page: 1, limit: 10, sort: { 'createdAt': 'desc' } }, function (){});

Priority-Web-SDK: Filtering a form

I am trying to understand how to use the setSearchFilter function in the Priority Web SDK. I can run formStart() followed by form.getRows(1) to get the entire form, but I only need ~5 of the over 100 rows.
login(configuration)
.then(() => formStart('ORDERS', null, null, 'demo',1))
.then(form => form.setSearchFilter({
or: 0,
ignorecase: 1,
QueryValues: [{
field: 'TOTPRICE',
fromval: '100',
op: '>'
}]
}))
.then(filter => filter.getRows(1))
.then(rows => console.log(rows))
.catch(err => console.log(err));
If I comment out the then-setSearchFilter line, I get the entire form. With it in, I get filter undefined.
This is for a phone app so how much data I download seems important.
As you can see in the documentation setSearchFilter doesn't return a filter object. After defining the filter each call to getRows will return rows according to the filter. You should call it like this: form.getRows not filter.getRows.
In addition, when defining a Filter you must define all of its members.

Sequelize Migration: update model after updating column attributes

I will get through to the point already. I'm having a problem of updating the rows after I have changed the status column attribute.
up: function(queryInterface, Sequelize) {
return queryInterface.changeColumn('projects', 'status', {
type: Sequelize.ENUM('processing', 'unassigned', 'ongoing', 'completed'),
allowNull: false,
defaultValue: 'unassigned'
}).then(function() {
return Project.update({
status: 'unassigned'
}, {
where: {
status: 'processing'
}
});
});
}
The Project.update() seems not working in any case but changing the attributes of the column works.
Any idea guys? I'm somehow a newbie in sequelize and any idea would be a great help. Thanks.
Depending on how you execute the migration ( via sequelize-cli or programmatically via umzug ). There is a different way to expose the table via the ORM.
In your case you have queryInterface passed as an argument to your function. So you can do a "raw query" via the attached sequelize property.
up: function(queryInterface, Sequelize) {
return queryInterface.changeColumn('projects', 'status', {
type: Sequelize.ENUM('processing', 'unassigned', 'ongoing', 'completed'),
allowNull: false,
defaultValue: 'unassigned'
}).then(function() {
return queryInterface.sequelize
.query("UPDATE projects SET status='unassigned' WHERE status='processing'");
});
}
By doing this you will make a raw Query to your database.
You can check out this gist for more details on an advanced way of using the ORM inside the migration.
I'm a fan of using umzug programmatically, which executes the migrations and also provides the initialized models of your database. If you configure it properly, you will benefit the exposed models ( e.g. sequelize.model('project').update() ) and have a better looking code.

Sequalizejs adding paranoid configuration to an existing table

I created a table without the paranoid option, and i now want to change that table's definition to use paranoid.
I don't want to re-create the database since its already in production.
how can i do that using migrations?
should i use addColumn with deletedAt and just add the paranoid definition to the model, or is there a better way?
I added the deletedAt field using migration like this:
"use strict";
module.exports = {
up: function(migration, DataTypes, done) {
// add altering commands here, calling 'done' when finished
migration.addColumn(
'mytablename',
'deletedAt',
{
type: DataTypes.DATE,
allowNull: true,
validate: {
}
}
);
done();
},
down: function(migration, DataTypes, done) {
// add reverting commands here, calling 'done' when finished
migration.removeColumn('mytablename', 'deletedAt');
done();
}
};
And added the configuration:
paranoid: true,
to my model
It seems to work.
Does anyone have a better solution?
Small update.
According to the sequelize version 6.4.0(what I am currently using), the migration looks like this:
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.addColumn(
'TABLE_NAME',
'deletedAt',
{
allowNull: true,
type: Sequelize.DATE
})
},
down: (queryInterface, Sequelize) => {
return queryInterface.removeColumn('TABLE_NAME', 'deletedAt')
}
};
I mean that the done method is not required.

Categories

Resources