silence the updatedAt field with Sequelize - javascript

I would like to disable or silence the updatedAt field when I update a record. As per sequelize docs looks like this option was available on v5.9.2.
my sequelize version: ^5.22.5
I've tried the following however it performs the update but still proceeds to update the updatedAt field in the DB.
#1
model.update(
{
count: Number(model.count) + 2,
},
{
where: {
id: 10
},
silent: true
}
);
#2
model.increment('count', { by: 2, where: { id: 10 }, silent: true });
#3
model.save ({ silent: true })

silent is the app-level functionalities not to update the updatedAt column, however, if you have ON UPDATE CURRENT_TIMESTAMP, this is the DB-level automatic update on the column.
TL;DR
silent works by not passing updatedAt to UPDATE query. So if the DB's column doesn't have any automatic assignment, by not passing the new value for updatedAt, the column value should stay the same. While, if you have automatic update on the DB's column, not passing the value means it allows DB to automatically assign the new value.
How I can do "silence" without updating DB schema
To disable the DB's automatic field, you can pass the value that you want to assign for the column. By default, Sequelize also has an automatic assignment of updateAt column, so we need to overwrite it.
const model = sequelize.define('MyModel',
{
count: {
type: DataTypes.INTEGER
}
},
{
hooks: {
beforeUpdate: (record, options) => {
if(options['custom_silent']) { // Add my custom silencing option
// If custom_silent is true, pass previous(current value in DB) updatedAt value and assigned to it
record.dataValues.updatedAt = record._previousDataValues.updatedAt
}
// If custom_silent is not true, use default Sequelize behavior (updatedAt = (current timestamp))
}
}
}
)
How to use it
await modelInstance.update(
{
count: modelInstance.count + 1000,
},
{
custom_silent: true
}
);

Related

How can I update an already stored boolean value in prisma with mongoDB?

I am using prisma with mongoDb for the first time and I want to update a boolean value stored in a collection, but I am not able to find a way/query to update the value from true to false or vise versa...:(
const updateUser = await prisma.user.update({
where: {
userToken: token,
},
data: {
isOnline: true,
},
})
I have this 'isOnline' stored as false default and this is what I have tried wrt prisma official documentation, but this did not worked for me
I think you are looking for set
const updateUser = await prisma.user.update({
where: {
userToken: token,
},
data: {
isOnline: {
set: true
},
},
})
Since true and false values could be mistaken as a special instruction in "prisma logics", the response from #Fastnligth should be the correct one -did't tried that though-.
Since Prisma ORM implemented MongoDB as an after thought, some of these functionalities might "seem a bit off".
I've arrived here trying to update an embedded field without updating the whole document, just the given field.
Leaving my two cents in case somebody else is having the same sailing over google ⛵️
You can do that as follows
const order = await prisma.order.update({
where: {
id: 'some-object-id',
},
data: {
shippingAddress: {
// Update just the zip field
update: {
zip: '41232',
},
},
},
})
official docs: https://www.prisma.io/docs/concepts/components/prisma-client/composite-types

Mongodb findOneAndUpdate - check if new document added, or just updated

I have the following code which is finding and updating an employee-store record (if it exists, otherwise it creates one).
I have lots of employees in different stores, and they can choose to change store at any point (as long as the location is in America)
Below is my code so far:
employee = await this.employeeStoreModel.findOneAndUpdate(
{ employee: employeeRecord._id, location: "America" },
{
employee: employeeRecord._id,
store: employeeRecord.store,
location: "America",
},
{ new: true, upsert: true }
);
This works correctly, however I am trying to return some messages from this based on what is being updated. It could be any of the following messages:
If it's a completely new employee-store record being added, then return "{{StoreID}} has a new employee - {{EmployeeID}}"
If it's a change of store on an existing employee-store record, then return "{{EmployeeID}} has changed from {{old StoreID}} to {{new StoreID}}"
Is this possible to do? Can anyone guide me on how I could start this?
In the Options field,
rawResult: true
You must add the parameter.
The result will be as in the example below.
{ response:
{ n: 1,
updatedExisting: false,
upserted: 5e6a9e5ec6e44398ae2ac16a },
value:
{ _id: 5e6a9e5ec6e44398ae2ac16a,
name: 'Will Riker',
__v: 0,
age: 29 },
ok: 1 }
Depending on whether there is an update or insert in the updatedExisting field, you can return any message you want.

Retrive some columns of relations in typeorm

I need to retrieve just some columns of relations in typeorm query.
I have an entity Environment that has an relation with Document, I want select environment with just url of document, how to do this in typeorm findOne/findAndCount methods?
To do that you have to use a querybuilder, here's an example:
return this.createQueryBuilder('environment') // use this if the query used inside of your entity's repository or getRepository(Environment)...
.select(["environment.id","environment.xx","environment.xx","document.url"])
.leftJoin("environment.document", "document")
.where("environment.id = :id ", { id: id })
.getOne();
Sorry I can't add comment to post above. If you by not parsed data mean something like "environment.id" instead of "id"
try this:
return this.createQueryBuilder("environment")
.getRepository(Environment)
.select([
"environment.id AS id",
"environment.xx AS xx",
"document.url AS url",
])
.leftJoin("environment.document", "document")
.where("environment.id = :id ", { id: id })
.getRawOne();
Here is the code that works for me, and it doesn't require using the QueryBuilder. I'm using the EntityManager approach, so assuming you have one of those from an existing DataSource, try this:
const environment = await this.entityManager.findOne(Environment, {
select: {
document: {
url: true,
}
},
relations: {
document: true
},
where: {
id: environmentId
},
});
Even though the Environment attributes are not specified in the select clause, my experience is that they are all returned in the results, along with document.url.
In one of the applications that I'm working on, I have the need to bring back attributes from doubled-nested relationships, and I've gotten that to work in a similar way, shown below.
Assuming an object model where an Episode has many CareTeamMembers, and each CareTeamMember has a User, something like the code below will fetch all episodes (all attributes) along with the first and last name of the associated Users:
const episodes = await this.entityManager.find(Episode, {
select: {
careTeamMembers: {
id: true, // Required for this to work
user: {
id: true,
firstName: true,
lastName: true,
},
}
},
relations: {
careTeamMembers: {
user: true,
}
},
where: {
deleted: false,
},
});
For some reason, I have to include at least one attribute from the CareTeamMembers entity itself (I'm using the id) for this approach to work.

Sequelize custom validation - unable to access all fields in entity

I attempted to create a model in sequelize (say has 3 attributes, attrA, B, and C) with some custom validation logic. This tutorial helped me get most of it set up:
const Model = Sequelize.define('model', {
attrA: { type: Sequelize.STRING },
attrB: { type: Sequelize.STRING },
attrC: { type: Sequelize.STRING },
}, {
validate: {
someValidationLogic() {
// Do something with attrA,B,C
// if (this.attrA ... this.attrB ... this.attrC) throw new Error..
}
}
})
In the application logic however, only say, 2 out of the 3 attributes (A and B) need to be updated:
Model.update(
{
attrA: 'foo',
attrB: 'bar'
}, {
where: {
id: 1,
},
returning: true,
})
This results in that when the custom validation logic being called, in the this object accessed in the function, only attrA and attrB are defined in this, and attrC remained undefined. This causes the validation logic to fail because attrC cannot be read. Is there any way I can get the object visible from someValidationLogic() to have all attributes populated? Or should this "validation" shouldn't have been validation logic at all and should've been done on the application level?
Your validation logic could take in account the possibility of attrC not being defined :
validate: {
someValidationLogic() {
if (this.attrA !== 'undefined' && this.attrA === 'forbidden value' ) {
// throw new Error
}
}
}
But if your validation includes checking the provided values against current database values, then you would better handle this in the application layer : first recover the current database record, manipulate it as needed, then save it to database.

Update a row in nedb

I have the following data in nedb.
["UserId":"1446943507761","UserName":"xxx","link":"xxx.html","taskDone":"false","id":14,"_id":"fdaaTWSxloQZdYlT"]
["UserId":"1446943507761","UserName":"xxx","link":"xxx.html","taskDone":"false","id":1,"_id":"fzh2cedAXxT76GwB"]
["UserId":"1446943507761","UserName":"xxx","link":"xxx.html","taskDone":"false","id":0,"_id":"k4loE7XR5gioQk54"]
I am trying to update row with id 0 and set the value of taskDone to true. I use the following query to set the value to true
db.taskmap.update({ _id: "k4loE7XR5gioQk54", UserName:"xxx" }, { $set: { taskDone: "true"} }, function (err, numReplaced) {
console.log("replaced---->" + numReplaced);
});
It updates the value but it updates as a new row. It basically inserts a new row with same values except for the taskdone value as true. It does not delete the existing data. Hence in the final data table after update i get tow rows for id 0 with all values same except for the taskDone. I am not sure if i am doing anything wrong. It will be helpful if anybody can tell me a correct way of updating the value.
You should call db.loadDatabase(); again at the end of db.update(); to see, that no second row with the same _id: appears instead the specific doc gets directly updated.
Edit:
It appears that sometimes when you do db.update() the document that should be updated appears twice instead on the database. It happened to me when I was updating an entry in a list of servers, multiple entries with the modified values were appearing on the database. So to avoid this simply do the following. (I took the same code that was suggested as the answer)
db.update(
{ _id: "k4loE7XR5gioQk54", UserName:"xxx" },
{ $set: { taskDone: "true"} },
{},// this argument was missing
function (err, numReplaced) {
console.log("replaced---->" + numReplaced);
db.loadDatabase();
}
);
Doing this prevents this from happening. I tested it multiple times and the issue disappeared.
update wants four arguments
var Datastore = require('nedb');
var db = new Datastore();
db.insert(
[
{
"UserId":"1446943507761",
"UserName":"xxx",
"link":"xxx.html",
"taskDone":"false",
"id":14,
"_id":"fdaaTWSxloQZdYlT"
},
{
"UserId":"1446943507761",
"UserName":"xxx",
"link":"xxx.html",
"taskDone":"false",
"id":1,
"_id":"fzh2cedAXxT76GwB"
},
{
"UserId":"1446943507761",
"UserName":"xxx",
"link":"xxx.html",
"taskDone":"false",
"id":0,
"_id":"k4loE7XR5gioQk54"
}],
function (err, newDocs) {
// empty here
}
);
db.update(
{ _id: "k4loE7XR5gioQk54", UserName:"xxx" },
{ $set: { taskDone: "true"} },
{},// this argument was missing
function (err, numReplaced) {
console.log("replaced---->" + numReplaced);
}
);
// should give the correct result now
db.find({}).exec(function (err, docs) {console.log(docs);});

Categories