[BUG]: value.getTime is not a function
What version of drizzle-orm are you using?
0.30.10
What version of drizzle-kit are you using?
0.21.2
Describe the Bug
Bug Report: Error when using time-related queries
Description
When attempting to use time-related queries with drizzle-kit, I encounter an error. Specifically, the error occurs when trying to fetch records from the visits table where the createdAt timestamp is greater than or equal to the current time.
Code Snippets
Here is the code that produces the error:
const visits = await db.query.visits.findMany({
where: gte(tables.visits.createdAt, Date.now()),
})
Schema definition for the visits table:
export const visits = sqliteTable('visits', {
id: integer('id').primaryKey({ autoIncrement: true }),
// ....
createdAt: integer('created_at', { mode: 'timestamp' }).notNull().default(new Date().getTime()),
})
Error Message
Error: value.getTime is not a function
Expected behavior
No response
Environment & setup
No response
I don't have any issues with filtering, for your example, does gte(tables.visits.createdAt, new Date()) work?
I am getting the same error, TypeError: value.getTime is not a function, but only when updating. Here is my database schema.
createdDate: integer("created_date", { mode: "timestamp" })
.default(sql`(unixepoch())`)
.notNull(),
updatedDate: integer("updated_date", { mode: "timestamp" })
.$onUpdate(() => sql`(unixepoch())`)
.notNull(),
I suspect there is some epoch time vs JS date type issue. .$onUpdate(() => new Date()) works and so does setting it when updating with updatedDate: sql(unixepoch())``. It is just odd that it doesn't work in the schema onUpdate function.
@magicalpuffin
You should change type from integer into text My problem solved like this
@magicalpuffin I've got the same issue. I was happy to see that they added onUpdate but after refactoring to take advantage of it, I realized it didn't work on timestamps so I'm back to manually pushing updateOn values until it gets fixed.
I also don't want a text column, because it's a timestamp, not text.
Hopefully we see a fix soon, this one's really annoying.
I did find what seems to be a way to do it. As long as you're okay with epoch time.
export const tableName = sqliteTable("tablename", {
id: ...,
updated_at: integer("updated_at", { mode: "timestamp_ms" })
.$onUpdateFn(() => new Date()).$type<Date>(),
otherFields: ...
}
I've only tested this with SQLite, but it seems to be working for me.
The problem is the value is something like:
{"decoder":{},"shouldInlineParams":false,"queryChunks":[{"value":["(CURRENT_TIMESTAMP)"]}]}
So I just changed the line in 103 to:
const unix = value?.getTime?.() ?? Date.now();
I'm not sure why it's doing this and didn't have time to look into it further but here is a quick workaround.
Here is my patch file.
diff --git a/node_modules/drizzle-orm/sqlite-core/columns/integer.cjs b/node_modules/drizzle-orm/sqlite-core/columns/integer.cjs
index b3d1837..56eaf41 100644
--- a/node_modules/drizzle-orm/sqlite-core/columns/integer.cjs
+++ b/node_modules/drizzle-orm/sqlite-core/columns/integer.cjs
@@ -100,7 +100,7 @@ class SQLiteTimestamp extends SQLiteBaseInteger {
return new Date(value);
}
mapToDriverValue(value) {
- const unix = value.getTime();
+ const unix = value?.getTime?.() ?? Date.now();
if (this.config.mode === "timestamp") {
return Math.floor(unix / 1e3);
}
diff --git a/node_modules/drizzle-orm/sqlite-core/columns/integer.js b/node_modules/drizzle-orm/sqlite-core/columns/integer.js
index fa17466..06ebb75 100644
--- a/node_modules/drizzle-orm/sqlite-core/columns/integer.js
+++ b/node_modules/drizzle-orm/sqlite-core/columns/integer.js
@@ -68,7 +68,7 @@ class SQLiteTimestamp extends SQLiteBaseInteger {
return new Date(value);
}
mapToDriverValue(value) {
- const unix = value.getTime();
+ const unix = value?.getTime?.() ?? Date.now();
if (this.config.mode === "timestamp") {
return Math.floor(unix / 1e3);
}
Confirming that @grantbi's patch resolve the issue.
I think only the generated typing is wrong. When I ignore the Typescript errors and just pass in Date objects, it just works.
Edit: Using sqlite and fields like integer("updated_at", { mode: "timestamp_ms" })
I have a similar issue.
For this schema:
export const things = sqliteTable("things", {
id: text("id", { length: 21 })
.primaryKey()
.$defaultFn(() => nanoid()),
validFrom: integer("valid_from", { mode: "timestamp" })
.notNull()
.default(sql`(unixepoch())`),
validTo: integer("valid_to", { mode: "timestamp" }),
});
running this update fails:
db.update(things)
.set({
validTo: new Date(),
})
.where(eq(things.id,'1'));
with the same error:
Error: value.getTime is not a function
My issue above was not the problem, I removed the actual bug in my minimal reproduction.
I had another updatedAt column that had a .$onUpdateFn(() => sql`(unixepoch())`) which caused the issue, replacing that with .$onUpdateFn(() => new Date()) fixed it.
My issue above was not the problem, I removed the actual bug in my minimal reproduction.
I had another
updatedAtcolumn that had a.$onUpdateFn(() => sql`(unixepoch())`)which caused the issue, replacing that with.$onUpdateFn(() => new Date())fixed it.
Thanks, that seemed to resolve it for me too.