1

I'm using prisma ORM in my node.js project. I code in TypeScript. I have reverse engineered my postgresql database tables into prisma schema. Then I've generated prisma client with npx prisma generate. It has created all of the types that I need to work with the database, but they are not correct. Each table has a pair of types: [tableName]CreateInput and [tableName]uncheckedCreateInput (I don't know what is this one for).

For example my customers table has customersCreateInput and customersUncheckedCreateInput types. The customersCreateInput lacks the id column (this column is the most important one). The customersUncheckedCreateInput has all of the columns including the id, but it is optional there... Why prisma does this, and how can I fix it? I want to make it work correctly every time i run npx prisma generate. Please help me, I have searched google for few days, I've found some corresponding topics (they've discussed different problem but it was about unchecked types in prisma) but didn't understand what they are talking about there.

export type customersCreateInput = {
    customer_email: string
    phone: string
    first_name: string
    middle_name?: string | null
    last_name?: string | null
    password_hash: string
    registered_at: Date | string
    last_login?: Date | string | null
    comments?: string | null
    addresses?: addressesCreateNestedManyWithoutCustomersInput
    carts?: cartsCreateNestedManyWithoutCustomersInput
    order_items?: order_itemsCreateNestedManyWithoutCustomersInput
    orders?: ordersCreateNestedManyWithoutCustomersInput
  }

  export type customersUncheckedCreateInput = {
    id?: number
    customer_email: string
    phone: string
    first_name: string
    middle_name?: string | null
    last_name?: string | null
    password_hash: string
    registered_at: Date | string
    last_login?: Date | string | null
    comments?: string | null
    addresses?: addressesUncheckedCreateNestedManyWithoutCustomersInput
    carts?: cartsUncheckedCreateNestedManyWithoutCustomersInput
    order_items?: order_itemsUncheckedCreateNestedManyWithoutCustomersInput
    orders?: ordersUncheckedCreateNestedManyWithoutCustomersInput
  }

I create that table with this SQL qyery:

CREATE TABLE Customers (
  ID SERIAL PRIMARY KEY NOT NULL,
  Customer_Email varchar(50) UNIQUE DEFAULT null,
  Phone varchar(25) NOT NULL,
  First_Name varchar(40) NOT NULL,
  Middle_Name varchar(40) DEFAULT null,
  Last_Name varchar(40) DEFAULT null,
  Password_Hash varchar(100) NOT NULL,
  Registered_At timestamp NOT NULL,
  Last_Login timestamp DEFAULT null,
  Comments varchar(250) DEFAULT null
);

My generated prisma schema is the one below:

model customers {
  id             Int           @id @default(autoincrement())
  customer_email String        @unique @db.VarChar(50)
  phone          String        @db.VarChar(25)
  first_name     String        @db.VarChar(40)
  middle_name    String?       @db.VarChar(40)
  last_name      String?       @db.VarChar(40)
  password_hash  String        @db.VarChar(100)
  registered_at  DateTime      @db.Timestamp(6)
  last_login     DateTime?     @db.Timestamp(6)
  comments       String?       @db.VarChar(250)
  addresses      addresses[]
  carts          carts[]
  order_items    order_items[]
  orders         orders[]
}
Faig
  • 33
  • 10

1 Answers1

2

You have @default(autoincrement()) for id therefore you can let DB do the work and not pass it manually here, it will be controlled automatically on DB level to avoid conflicts and to simplify things for you.

But if you want to pass id you still can do it manually, this is why second type is there, it seems.

prisma generates two different types for some reason, and uses XOR type on them, so you can either use one or another, but not combination of them, like that:

  export type ExampleCreateArgs = {
    /**
     * Select specific fields to fetch from the Example
     * 
    **/
    select?: ExampleSelect | null
    /**
     * The data needed to create a Example.
     * 
    **/
    data: XOR<ExampleCreateInput, ExampleUncheckedCreateInput>
  }

For example, if you want to reuse that data type in your code you can do the following:

// substitute ExampleCreateArgs to correct one from your code
type Data = ExampleCreateArgs["data"]
Danila
  • 15,606
  • 2
  • 35
  • 67
  • Thank you very much for your answer! What about "[tableName]uncheckedCreateInput" what is it for? – Faig Jan 14 '22 at 15:55
  • I've updated my answer a bit, seems I was wrong that you cannot pass id in that case, you actually can, it seems that's why second type is here for – Danila Jan 14 '22 at 16:10
  • Ahh, now I understand why they've put the XOR here. It throws an error if you specify a combination right?( though it will throw an error only on mandatory fields :/ ) Right? – Faig Jan 15 '22 at 07:12
  • 1
    Probably yes! I guess it's also to handle more complicated cases when the difference is not only id but something else too – Danila Jan 15 '22 at 12:59
  • I think there is no documentation on what uncheckedCreateInput is used for. – Cesarvspr Jun 30 '22 at 00:52
  • Regarding missing documentation -- quite so, not directly, but [in a related question here on SO](https://stackoverflow.com/questions/68840391/unknown-argument-error-when-creating-record) there's a quick explanation: '[One can] either provide all references as `connect`, `create`, `relation`s.. (**`checked`**) or as raw `ID`s (**`unchecked`**). – Dr1Ku Dec 14 '22 at 20:02