drizzle-team / drizzle-orm

Headless TypeScript ORM with a head. Runs on Node, Bun and Deno. Lives on the Edge and yes, it's a JavaScript ORM too 😅
https://orm.drizzle.team
Apache License 2.0
21.44k stars 484 forks source link

[BUG]: Timestamp with null default, workaround quoted does not cater for generated SQL #2492

Open LlamaPony opened 2 weeks ago

LlamaPony commented 2 weeks ago
          I just ran the following query in MySql 8:
CREATE TABLE `users` (
     `id` serial AUTO_INCREMENT NOT NULL,
     `verified_at` timestamp,
     `deleted_at` timestamp,
     CONSTRAINT `users_id` PRIMARY KEY(`id`)
);

And it works as expected. Drizzle supports the latest in MySql unfortunately. But you have a workaround:

export const users = mysqlTable('users', {
     id: serial('id').default(sql`null`).primaryKey(),
     verifiedAt: timestamp('verified_at').default(sql`null`).$type<Date | null>(),
     deletedAt: timestamp('deleted_at').default(sql`null`).$type<Date | null>()
});

Originally posted by @Angelelz in https://github.com/drizzle-team/drizzle-orm/issues/1136#issuecomment-1810232933

workaround helps for typing in ide. although when i want to publish to my production database it errors at the timestamps, because the sql produces for timestamps with the default of null needs to have the "NULL" after the column datatype in some older mysql versions, any my hosting does not allow the option to change my mysql version.

Expected SQL statement to be generated: ...table declare start... deleted_at timestamp NULL DEFAULT NULL, ...table declare end...

The provided solution only caters for code side and needs the fix as mentions in expected SQL above please

LlamaPony commented 2 weeks ago

will it be possibly to add a .null() chain method when defining a model so you can explicitly tell the sql generater to generate the correct SQL code?

only workaround for the SQL side of code is to manually to a ctrl + find all then replace the timestamps allowed to be null to have the "NULL" keyword after the timestamp datatype.

currently the solutions given ONLY caters for the typescript when coding and does NOT generate the correct SQL code.

i am unable to modify my live server environment's database settings since its in a hosted renting environment by asurahosting.

when i run SELECT VERSION() in phpmyadmin i get "mariadb" in which the sql syntax "timestamp default null" is invalid, and the correct code should be "timestamp null default null"

LlamaPony commented 1 week ago

a .null() chain function on the model definition would solve this dilema, please implement a .null() chain function for models to explicitly mark a column to have the null keyword after its datatype in the generated sql code.

current workaround with sql code is , use drizzle-kit to create a migration then open the .sql file(s) generated and where i have nullable timestamps that default to null i have to manually add the keyword NULL after each datatype.

if someone could implement the .null() chain function to explicitly mark a column as needing the null keyword after its datatype would safe 10 minutes per deployment of time, as i have to manually find and replace them. a find all and replace will affekt the columns that should not be nullable,