-
-
Notifications
You must be signed in to change notification settings - Fork 634
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
[Pg] Fix: all datetime mappings #1659
[Pg] Fix: all datetime mappings #1659
Conversation
This will also close #1061 |
Just hit this issue, thanks for looking into it @Angelelz Closing 7 issues in one 🚀 🚀 🚀 🚀 🚀 🚀 🚀 |
Am waiting for this to merge before giving a migration from prisma a test |
@Angelelz, thanks for your PR. Are those changes compatible with the previous implementation? |
Before, the user was being lied to by the types when using the postgres.js driver. Drizzle was expecting to receive a string, and was reporting a string and not doing any mapping, but postgres was actually returning a Date. That's why so many issues were filed. With this PR the mapping made by postgres.js has been disabled, so drizzle maps correctly as the user requests with the BTW, I see conflicts, I thought I resolved them all last night. Let me see if I can resolve here in GH. |
This is 100% what's happening...even if you set mode = "string" it returns a date object (but the type is a string). I'm having to do a quick transform from date -> string before returning results, just to get the data to sync with the types. Really looking forward to this PR getting merged :-) |
Does this resolve #1164 |
Based on this test added, if it passes then yes. But I think that test only runs when merging to beta or main. I didn't run it locally. Crucially, the mapping I did in |
@AndriiSherman Can you run the test on AWS locally to know for sure? I don't have an account, nor I want to create one lol |
Actually, this might have already been fixed by this commit. |
Yes, I wanted to test Serverless v2 anyway, so I'm going to run all tests for the AWS Data API and merge if successful. Also, @Angelelz, I guess mappings in the timestamp can be reverted. We will always get a string from the driver, as long as in both pg and postgres.js, we are receiving a raw response, which is always a string for dates. I think, in this case, it should be compatible with the previous version and still work as expected. I also think that it may be a breaking change for someone who is doing custom mapping, so I guess we would need to make a minor release and not a patch release and add this to the docs. Maybe we can finally add release notes or tags to mark it somehow |
@AndriiSherman related issue: #1686 |
I guess you need to create another tests for First case(
Second case(
Third case(
And a few more tests for just First case(
Second case(
Third case(
|
Hey Andrew, |
@AndriiSherman I added the tests on all 5 pg drivers. the big problem is that I couldn't run the tests locally on AWS or Neon, because I don't have accounts on either of those. I basically guessed the types of the raw select when using |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@AndriiSherman I have added the requested tests. I also decided to add the requested tests on the postgres.js.test.ts since that's the driver where I made the changes to the mappings. |
just left 1 comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
integration-tests/tests/pg.test.ts
Outdated
// 2, Select in string format and check that values are the same | ||
const result = await db.select().from(table); | ||
|
||
t.deepEqual(result, [{ id: 1, timestamp: '2022-01-01 04:00:00.123456+00' }]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we don't need this specific test, because you have 2 proper tests with different timezones added
integration-tests/tests/pg.test.ts
Outdated
|
||
// Please notice that postgres will transform the date to UTC and it saves it in UTC. | ||
// even if set without time zone, just becuase it was provided a timezone offset, it will transform it to UTC | ||
t.deepEqual(result.rows, [{ id: 1, timestamp_string: '2022-01-01 04:00:00.123456+00' }]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As Postgres docs states
In a literal that has been determined to be timestamp without time zone, PostgreSQL will silently ignore any time zone indication. That is, the resulting value is derived from the date/time fields in the input value, and is not adjusted for time zone.
This means that when you insert a string with a timezone into a timestamp without time zone
type, the timezone should be simply removed without any time conversions. For example, for 2022-01-01T02:00:00.123456-02
, you should receive 2022-01-01 02:00:00.123456
in return
The reason why it happened - you have created timestamp(6) with time zone
instead of timestamp(6)
integration-tests/tests/pg.test.ts
Outdated
await db.execute(sql` | ||
create table ${table} ( | ||
id serial primary key, | ||
timestamp_string timestamp(6) with time zone not null |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should be just timestamp(6)
integration-tests/tests/pg.test.ts
Outdated
await db.execute(sql` | ||
create table ${table} ( | ||
id serial primary key, | ||
timestamp_string timestamp(3) with time zone not null |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should be just timestamp(6)
@Angelelz, while you are fixing what I found, I'll start writing documentation for timestamps with explanations on how it should work with Postgres now. I want to make sure everybody will know exactly how we are handling it |
@AndriiSherman sounds good, thank you for being so thorough. Will address these later today. |
Will this fix the issue where I have date columns in Postgres and Date objects that I am trying to insert but Drizzle makes me convert them to strings first? |
@AndriiSherman You were totally right, I had made the mistake of setting the columns with time zone and thought that postgres were transforming them internally. |
Nice work @Angelelz and thanks for the review @AndriiSherman This one is really important for our team |
This pull request will be merged into the |
This PR will also close 895 |
This PR will close #806, close #971, close #1176, close #1185, close #1407 and close #1587.
Most are the same. The problem is postgres.js, it didn't have a clear way of replace the default parsing into a Date object after the client have been instantiated.
I spent some time researching and found a solution.
Although it looks like postgres.js is still trimming the microsecond precision, even after bypassing the parsing.
I'll look into it further and possibly submit a new PR.
Added tests on all/most drivers that use postgres.
Edit: I found another workaround for the issue with trimming the microsecond precision. I added the commit.