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.52k stars 487 forks source link

[BUG]: TypeError: Do not know how to serialize a BigInt #2382

Closed alpapan closed 4 hours ago

alpapan commented 1 month ago

What version of drizzle-orm are you using?

0.30.10

What version of drizzle-kit are you using?

0.21.4

Describe the Bug

Putting here in case it is of help:

When using Drizzle with fastify/view (8.2.0) and nest js (10), bigserials have a mode of bigint which croaks due to json stringify (see this fastify issue and stringify

The following was created by drizzle-kit with a postgres schema that has id as a bigserial and it will croak with TypeError: Do not know how to serialize a BigInt

export const users = pgTable(
  'users',
  {
    id: bigserial('id',{mode: 'bigint'}).primaryKey().notNull(),
    username: varchar('username').notNull(),
[..]

The quick solution is to change the mode from bigint to number.

   id: bigserial('id',{mode: 'number'}).primaryKey().notNull(),   

I'm not sure if it is perhaps a good idea to either document or set the default drizzle-kit output to mode: number

I note that when drizzle-kit sees a bigint column that is not (big)serial, then it sets the mode to number by default and provides a comment. So perhaps this could apply to bigserial too (since these two things are linked in the database: a bigserial id may have a bigint foreign key somewhere.

DRIZZLE-KIT output from introspect:

  // You can use { mode: "bigint" } if numbers are exceeding js number limitations
  user_id: bigint('user_id', { mode: 'number' })
    .notNull()
    .references(() => users.id, { onDelete: 'cascade', onUpdate: 'cascade' }),

Expected behavior

No response

Environment & setup

"dependencies": {
    "@fastify/static": "^7.0.4",
    "@fastify/view": "^8.2.0",
    "@knaadh/nestjs-drizzle-postgres": "^1.0.0",
    "@nestjs/common": "^10.3.8",
    "@nestjs/config": "^3.2.2",
    "@nestjs/mapped-types": "*",
    "@nestjs/platform-fastify": "^10.3.8",
    "@nestjs/serve-static": "^4.0.2",
    "@nestjs/swagger": "^7.3.1",
    "class-transformer": "^0.5.1",
    "class-validator": "^0.14.1",
    "dotenv": "^16.4.5",
    "drizzle-orm": "^0.30.10",
    "handlebars": "^4.7.8",
    "js-yaml": "^4.1.0",
    "postgres": "^3.4.4",
    "reflect-metadata": "^0.2.2",
    "rxjs": "^7.8.1",
  },
  "devDependencies": {
    "@fastify/static": "^7.0.4",
    "@fastify/view": "^8.2.0",
    "@knaadh/nestjs-drizzle-postgres": "^1.0.0",
    "@nestjs/cli": "^10.3.2",
    "@nestjs/common": "^10.3.8",
    "@nestjs/config": "^3.2.2",
    "@nestjs/core": "^10.3.8",
    "@nestjs/platform-fastify": "^10.3.8",
    "@nestjs/schematics": "^10.1.1",
    "@nestjs/serve-static": "^4.0.2",
    "@nestjs/swagger": "^7.3.1",
    "@nestjs/testing": "^10.3.8",
    "@swc/cli": "^0.3.12",
    "@swc/core": "^1.5.7",
    "@types/express": "^4.17.21",
    "@types/jest": "^29.5.12",
    "@types/js-yaml": "^4.0.9",
    "@types/node": "^20.12.12",
    "@types/supertest": "^6.0.2",
    "@typescript-eslint/eslint-plugin": "^6.21.0",
    "@typescript-eslint/parser": "^6.21.0",
    "class-transformer": "^0.5.1",
    "class-validator": "^0.14.1",
    "drizzle-kit": "^0.21.4",
    "drizzle-orm": "^0.30.10",
    "globals": "^15.3.0",
    "handlebars": "^4.7.8",
    "jest": "^29.7.0",
    "postgres": "^3.4.4",
    "prettier": "^3.2.5",
    "reflect-metadata": "^0.2.2",
    "source-map-support": "^0.5.21",
    "supertest": "^6.3.4",
    "ts-jest": "^29.1.3",
    "ts-loader": "^9.5.1",
    "ts-node": "^10.9.2",
    "tsconfig-paths": "^4.2.0",
    "tsx": "^4.11.0",
    "typescript": "^5.1.3"
  },
bondz commented 2 weeks ago

The issue here is not with drizzle. Drizzle returns the correct datatype for the column as specified in the schema. The issue is when you want to send it via fastify to the client, and it doesn't only affect fastify, express too would be affected. You can serialize the data yourself before sending it to the client. See options here

alpapan commented 1 week ago

Perhaps. But if you notice my post you will see that foreign key references are set the mode to number even if the referenced column is a bigserial/bigint.

It would work out of the box if drizzle was consistent and set the mode to number for bigserial during column definition and provided the same comment as it does for columns with foreign key references.

If it was me, I would make sure the mode was identical in both definitions, both bigint or number. I would also add a note in the documentation somewhere.

Up to you if you and how you want to interact with the user community. After an hour I learnt how to fix it on my system.