-
-
Notifications
You must be signed in to change notification settings - Fork 4.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to manually set updatedAt / createdAt #3759
Comments
Yeah, this usecase is not really supported I guess - save will always set updatedAt to the current timestamp, unless you set silent to true, in which case it will ignore it completely. I guess it actually makes to only set updatedAt if changed returns false |
@stephenjwatkins as a work around you could use sinon clock for testing. |
@mickhansen I appreciate the suggestion. I will indeed use sinon clock for testing to work around this. |
i wish there was a "force" flag for .save() on an instance, that just set the updatedAt flag even if nothing was changed. Im trying to use updatedAt field as a timestamp of the last time a record was known to be valid, since i'm syncing stuff in my db with a 3rd party's db. That way I can purge items from my db that are stale. i dont want to create a new column for this if i could just get the same functionality out of the updatedAt field |
@ssteffl you can do |
ok cool. that seems to work. im just doing:
and it seems to be setting the updatedAt correctly. Thanks! |
@mickhansen Any idea if it's possible to do this without using raw sql? (ie using the sequelize instance API). My use case is that I am creating/updating entities in an offline application (uuid primary key) and setting updatedAt in that application. The application syncs with an online database via a node API using sequelize. The "updated" Accepting PRs for this? |
Additionally, if this is something that you would be open to having implemented, do you have any opinions on what the user should pass in terms of options to the set+save/update/etc functions? I haven't contributed before here and not sure what the most idiomatic option is. |
A PR adding a |
Hey Mick, I implemented this last night. It required modifying the set function too. Otherwise it is caught on the read only check. I can provide more details when I'm on my computer. I have this running, with a test, albeit with a different option name. (I used |
Should be no need to modify the set function. |
Regarding your other point - this would mean that the user would have to call set twice if they don't want to set all the data using At the moment, if you call set with I can't speak for others -- but my use case would still benefit from proper validation + invoking of virtual setters for the other columns. The goal of this in my eyes is to be able to set the timestamp manually without compromising the other columns. However, this isn't my library -- if you want to restrict this functionality to updating/setting using One more thought about |
@nathanmarks Hm, i might have missed what you're intending to do here, are you overwriting updatedAt manually or are you trying to have Valid comment about |
Basically, I have entities being created + updated in an offline context. When the application syncs with the online API, assuming everything is a-okay, I want to retain the For syncing offline, cross-device, it's important that the Here's a contrived example: const twoHoursAgo = new Date(Date.now() - 7200000);
const newData = {
id: 'abcd-1234-5678-0123',
name: 'Foo',
updatedAt: twoHoursAgo
};
Model.findById(newData.id).then(instance => {
// if null, create
// or if found..... then update
return instance.update(newData, {
forceTimestamps: true
});
}).then(instance => {
// updatedAt should be my provided date (2 hours ago), not Date.now()
}); |
Hmm okay, not sure how we solve that best actually. |
@mickhansen I have an implementation running but it isn't necessarily 10000% ideal as it requires the option is passed to both set and save if you call them separately. (If using update, obviously you just pass it the once). It also allows you to pass in the option to |
Does |
@mickhansen Not working for me. Something interesting to note though, consider the following test: it('updates timestamps when passing forceTimestamps=true', function() {
var self = this;
return this.User.create({ username: 'user' }).then(function(user) {
var updatedAt = new Date(Date.now() - 7200000);
user.set({
updatedAt: updatedAt
}, { raw: true });
return user.save({
silent: true,
fields: ['updatedAt']
}).then(function(user1) {
expect(user1.updatedAt).to.equalTime(updatedAt); // THIS PASSES
return self.User.findById(user1.id);
}).then(function(user2) {
expect(user2.updatedAt).to.equalTime(updatedAt); // THIS FAILS
});
});
});
I know it adds an extra option -- but do consider that the implementation I've already outlined is only about 12 LoC excluding tests and docs with a much cleaner usage example. EDIT and it also retains virtual setter etc... functionality for other columns and does not skip checking for other read-only columns, allowing you to call |
Hmm, that line might be redundant since we do changed/fields checks earlier in the process. |
@mickhansen Ignore the name of the option as it's currently As a side node, in the test I embedded inline above, is the first expectation passing by design? It seems weird that I can get a successful promise fulfillment from save containing an attribute that was not committed to the database. |
@nathanmarks Sequelize calls always return promises, regardless of whether or not it was a no-op internally or not. I'm trying to figure out the best way to solve this. |
@mickhansen The issue isn't a promise being returned (most of my JS apps involve promise consumption, usually with a heavier sprinkling of rejection than sequelize though) -- it just seems counterintuitive that the This resulted in a test I wrote showing a false positive because I was checking the I modified my test case to use Given the current description of
The other main issue with that is that it would prevent using I haven't tested this yet (about to) but i'm also going to be pushing a client generated Just to summarize, these are the needs:
|
@nathanmarks It was a workaround suggestion, not the way i'd like it to work moving forward. |
@mickhansen want a PR with a failing test when checking the attributes of an instance returned from Right now for a workaround I'm going to rebase my branch as the proposed method doesn't seem to work. I totally agree about the terminology, however things like An alternative option is to open up the |
@mickhansen Let me know if you want to see a proof of concept for the |
@nathanmarks A test would be great. I'm not at all sure how to solve this best, i'd love to see a proposal in a PR. |
@mickhansen I'll submit a failing test for that separate issue and put together a PR for the timestamp conundrum! Totally understand if you're on the fence and not sure -- but if you could let me know whether you prefer an additional option or potentially leveraging the |
Poking my head in to say a I tried |
instance.changed("updatedAt", true); updatedAt updated to Date.now() works like charm! |
For the next poor soul, when upgrading to Sequelize 5 beware that if you set |
Hi @rsshilli can you please create an SSCCE to show what you mean? |
Actually, I think the Sequelize 5 code is the right way to do it. There's nothing to fix. Setting |
I also needed to be able to force a value for timestamps in a test context. I managed to force a value for timestamps by running a separate query that converts an instance to a simple SQL statement. Your backend DB may require different syntax, but the premise here should get you where you want to go. Note that I'm using Sequelize 3.
|
As mentioned into the documentation
|
you're right, thanks for the correction |
How can we set We don't want to set the date from nodejs (slightly different), also don't want to use db triggers. Answer: |
I encountered this problem while trying to implement database-agnostic DB backup of json files. My solution was to set model definination |
Any progress here? |
Why is this issue still open? There's nothing to fix. |
@rsshilli Using the latest release of Sequelize I'm unable to set createdAt/updatedAt to a specific date using any listed workaround in this thread. Even a raw SQL query using sqlite as the backend doesn't work :( |
I've tried a lot of stuff, but this helped me https://stackoverflow.com/a/52415630/5225096
|
try manual update sequelize.getQueryInterface().queryGenerator.updateQuery(
'YOU_TABLE',
{ updated_at: sequelize.literal('CURRENT_TIMESTAMP') },
{ id: 1 },
{ returning: false },
)
sequelize.query(query) |
I want to set updatedAt manually while creating object |
This worked for me. Thanks @arnaudambro |
Found on StackOverflow. works for me... https://stackoverflow.com/questions/64250923/change-value-of-createdat-in-sequelize const yesterday = ( d => new Date(d.setDate(d.getDate()-1)) )(new Date);
hang.changed('createdAt', true);
hang.set('createdAt', yesterday,{raw: true});
await hang.save({ silent: true, fields: ['createdAt'] });
// "sequelize": "^6.29.3",
// "sequelize-cli": "^5.5.1", |
Is any TS solution?, I got It is not possible to assign an argument of type ""updatedAt"" to the parameter of type "keyof Model<any, any>". when using changed() |
Struggling with the same TS issue |
I'm working on some tests and I need to manually set the
updatedAt
attribute. However, it always gets updated to the current date. For example, the following code does not override theupdatedAt
attribute, as I expected it to:Am I missing something related to the proper use of
silent
?I'm running on v2.1.3.
The text was updated successfully, but these errors were encountered: