prisma / prisma

Next-generation ORM for Node.js & TypeScript | PostgreSQL, MySQL, MariaDB, SQL Server, SQLite, MongoDB and CockroachDB
https://www.prisma.io
Apache License 2.0
38.35k stars 1.49k forks source link

`yarn prisma generate` has stopped updating types when `prisma.schema` changes. #22534

Open dawnmist opened 6 months ago

dawnmist commented 6 months ago

Bug description

Seen in prisma 5.7.0 + 5.7.1 with yarn 4.0.2 using the pnpm linker.

I have been modifying the types of some columns in the db to be unique, and after editing the prisma.schema file and saving the changes, running yarn prisma generate produces no errors but doesn't actually update the generated types files resulting in the schema changes not being reflected in the types.

Removing the .yarn/install-state.gz file so that yarn thinks the packages haven't been installed yet results in the next yarn install updating the types package properly.

Upgrading from prisma 5.7.0 to 5.7.1 also results in the types being updated properly during that upgrade.

Both of the above represent situations where yarn believes that that package is either not installed yet, or is having it's version number updated. Without one of those two conditions being present yarn isn't recompiling/regenerating the node_modules/.prisma/client bundle when running prisma generate resulting in the old types continuing to be used.

This used to work, and I'm not sure when it broke. It was previously working on yarn 3.x with prisma 4.16, but I hadn't needed to make DB changes for a while so I don't know if a specific prisma update or the yarn update from 3.x to 4.x broke it.

How to reproduce

I have created a repository that can easily reproduce the issue at: https://github.com/dawnmist/prisma-generate-repro

Steps to reproduce:

Expected behavior

The change to add the @unique tag to the email field should be reflected in the .prisma/client package after running yarn prisma generate, not be waiting for a manual rebuild of the package.

Prisma information

generator client {
  provider        = "prisma-client-js"
  previewFeatures = ["metrics", "multiSchema", "postgresqlExtensions", "tracing", "views", "relationJoins"]
}

datasource db {
  provider   = "postgresql"
  url        = env("DATABASE_URL")
  directUrl  = env("DIRECT_URL")
  extensions = [pg_graphql, pg_stat_statements, pgcrypto, pgjwt, pgsodium, pgtap, plpgsql, uuid_ossp(map: "uuid-ossp")]
  schemas    = ["app", "auth", "extensions", "realtime", "storage", "stripe"]
}

model StripeCustomer {
  id            String   @id
  createdAt     DateTime @default(now()) @map("created_at") @db.Timestamptz(6)
  customerName  String   @map("customer_name")
  description   String?
  delinquent    Boolean  @default(false)
  email         String
  invoicePrefix String?  @map("invoice_prefix")
  userEmail     String   @unique @map("user_email")

  @@map("stripe_customers")
  @@schema("stripe")
}

Environment & setup

Prisma Version

prisma                  : 5.7.1
@prisma/client          : 5.7.1
Computed binaryTarget   : debian-openssl-1.1.x
Operating System        : linux
Architecture            : x64
Node.js                 : v18.12.1
Query Engine (Node-API) : libquery-engine 0ca5ccbcfa6bdc81c003cf549abe4269f59c41e5 (at node_modules/.store/@prisma-engines-npm-5.7.1-c8a79e8ec6/package/libquery_engine-debian-openssl-1.1.x.so.node)
Schema Engine           : schema-engine-cli 0ca5ccbcfa6bdc81c003cf549abe4269f59c41e5 (at node_modules/.store/@prisma-engines-npm-5.7.1-c8a79e8ec6/package/schema-engine-debian-openssl-1.1.x)
Schema Wasm             : @prisma/prisma-schema-wasm 5.7.1-1.0ca5ccbcfa6bdc81c003cf549abe4269f59c41e5
Default Engines Hash    : 0ca5ccbcfa6bdc81c003cf549abe4269f59c41e5
Studio                  : 0.495.0
Preview Features        : metrics, multiSchema, postgresqlExtensions, tracing, views, relationJoins

Also observed on prisma 5.7.0.

jkomyno commented 6 months ago

Hi @dawnmist Thanks for opening this issue.

With

yarn 4.0.2 with pnpm linker

are you referring to this yarn 4 setting?

Did you encounter this issue only after upgrading yarn from version 3.x to 4.x? When did you try upgrading prisma's version, before or after upgrading yarn?

If you only started encountering this issue after upgrading yarn, may we suggest to open a new issue in yarn's repository directly, and add a backlink here? Thanks!

dawnmist commented 6 months ago

@jkomyno - I have now tried stepping the example repo back to using yarn 3.7.0, and can confirm that yarn prisma generate works reliably in yarn 3 but not in yarn 4.

I have been through multiple upgrades of both prisma and yarn between the time I was last updating my schema and now. When I was last making schema changes, the versions of each in use had been yarn 3.6 with prisma 4.16. The schema had been stable for several months, so I'd been through multiple upgrades of both prisma and yarn in between when it was last known working and now.

Yes, I was talking about the nodeLinker setting set to pnpm as per the .yarnrc.yml file in the example repository provided https://github.com/dawnmist/prisma-generate-repro/blob/main/.yarnrc.yml The pnpm setting uses symlinks in the node_modules folder to the expanded package files like the pnpm package manager does, which makes it easier to debug/investigate issues than their pnp nodeLinker and with better package compatibility since there is still a recognisable node_modules directory, while still being faster/less disk usage than the original npm style installations.

dawnmist commented 6 months ago

Tested stepping between yarn versions - it's the entire yarn 4.0.0 to 4.0.2 line where this is not working.

There does appear to have been a change to how the pnpm linker stores the generated prisma package on disk, which is resulting in the .prisma/client directory existing as its own package instead of inside the same @prisma-client-virtual package that is created from @prisma/client.

You can step between yarn versions using yarn set version <X> in the example repo.

The node_modules/.store directory is where the package files get extracted into versioned directories in both yarn versions, but within yarn 4 they've changed the layout of those unpacked directories and this is resulting in the .prisma/client directory moving out of the @prisma-client-virtual package. Hard to describe with words so I've added screenshots below.

Yarn 3 node_modules: image

Yarn 4 node_modules: image

kopax commented 3 weeks ago

Is this still up ? I am trying to fix the yarn prisma generate on yarn 4 and I am not sure what to do...

dawnmist commented 3 weeks ago

@kopax - I found 2 work-arounds:

  1. create a yarn script that runs both commands: e.g.
    {
    "scripts": {
    "generate": "yarn prisma generate && yarn rebuild @prisma/client"
    }
    }

OR

  1. Change from using the pnpm linker back to the node_modules linker.

I ended up going with option 2 due to show-stopping issues with other libraries that were also being caused by the pnpm linker and how it changed the on-disk layouts for npm modules in yarn 4+. It broke the ability to instrument my application with opentelemetry, broke esbuild's compiler, broke prisma generate, and broke some of the sentry scripts - it just got to be too many issues for me to continue with the pnpm linker. 😢

Druue commented 2 weeks ago

I can confirm that this worked on yarn3 but no longer on yarn4. I can also confirm that changing the linker from pnpm to node-modules resolves the issue, and that running yarn rebuild @prisma/client correctly updates types. I'm unfortunately not massively familiar with yarn and these options.

I'm assuming this .store directory with xyz-virtual folders is the result of store and symlinks it mentions:

If pnpm, a node-modules will be created using
symlinks and hardlinks to a global content-addressable store.