valtyr/prisma-kysely

[BUG] Prisma Decimal gets converted into kysely String

Closed this issue · 8 comments

When converting Decimal type of prisma, it converted into string instead of number.

Sample Schema:

generator kysely {
  provider     = "prisma-kysely"
  output       = "../src/kyselydb"
  fileName     = "kysely-types.ts"
  enumFileName = "kysely-enums.ts"
}

generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "cockroachdb"
  url      = env("DEMODEV_DATABASE_URL")
}
model TestModel {
    id                   String             @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid
   credit_rate      Decimal
}

the generated kysely types:

export type TestModel = {
	id: Generated<string>;
	credit_rate: string;
}
valtyr commented

I think this is actually the result type returned by the driver. Can you check?

@valtyr No, the mapping on this file is wrong for postgresql and mysql -> https://github.com/valtyr/prisma-kysely/blob/main/src/helpers/generateFieldType.ts

Cockroachdb is using postgresql driver

I can confirm the behavior:

prisma:
expires BigInt?

results in kysely:
expires: string | null

Using provider = "postgresql" here.

The node pg driver will in fact return a string for decimal and bigint types for technical reason (MAX_SAFE_INTEGER):
brianc/node-postgres#811 (comment)

You can setup pg driver to typecast numeric value:

import { types } from "pg";

types.setTypeParser(types.builtins.NUMERIC, (value) => Number(value));

And override types in your schema generator config:

generator kysely {
  provider            = "prisma-kysely"
  output              = "../src/kyselydb"
  fileName            = "kysely-types.ts"
  enumFileName        = "kysely-enums.ts"
  decimalTypeOverride = "number"
  bigIntTypeOverride  = "number"
}

I understand the MAX_SAFE_INTEGER problem in JS - but right here I don't think that is the problem.

I assume if you'd have a BigInt or similar in the database and you wouldn't use string in the kysely-types definition.
And this is what this is about, translation of a prisma schema to kysely types.

valtyr commented

@delight There's a file called src/dialectTests/postgresql.ts that runs a very simple test. It creates the database with all the types supported by prisma-kysely, queries all the fields, and prints out the typeof for all the fields. I used this to verify the types for each dialect when I wrote the initial versions of prisma-kysely. It confirms that the driver indeed returns a string type when querying a BigInt. Remember that prisma-kysely only operates in type land and has to be opinionated by default to support the types returned by the standard kysely driver for each dialect. If you want the string to be parsed into a BigInt object after a query, or if it turns out that you're using some non-standard driver or have configured it differently then I refer to @cahnory's solution above. If we were to change the type we would break prisma-kysely for everyone else. If you are interested in running the test for yourself, you can run docker compose up -d postgres in the root directory to boot a database and run yarn run build && node dist/dialectTests/postgresql.js to run the tests.

CleanShot 2023-11-01 at 10 19 49@2x
valtyr commented

Oh and here are the results for mysql:

CleanShot 2023-11-01 at 10 29 31@2x

Closing this as per my comments above.