Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for splitting Prisma schema into multiple files #2377

Labels
domain/psl Issue in the "PSL" domain: Prisma Schema Language domain/schema Issue in the "Schema" domain: Prisma Schema, Introspection, Migrations etc. kind/feature A request for a new feature. status/is-preview-feature This feature request is currently available as a Preview feature. topic: modular-schema topic: schema

Comments

@albertoperdomo
Copy link
Contributor

albertoperdomo commented May 5, 2020

Problem

Prisma currently only supports one single Prisma Schema file. Developers want more flexibility for managing their Prisma Schema files.

Motivations:

  • breaking up large schema files to make them more manageable
  • flexible integration with certain architectures, i.e. each module has its own self-contained logic including its schema

Solution

Support importing additional schema files, i.e. import "user.schema", import models/*.prisma or import modules/**/*.prisma.

Alternatives

Not researched at this time.

Additional context

#92

@ChristophDietrich
Copy link

Like prisma one ... there was a feature like this implemented.

@paniavula
Copy link

Appreciate prioritisation of this. It is really painful to write all the schema in one file.

@beeplin
Copy link

beeplin commented May 14, 2020

badly need this feature. currently I have to cat a.prisma b.prisma > schema.prisma. it works but is so clumsy.

@JontyCoertzen
Copy link

Any update on this?

@SteveSonoa
Copy link

Any movement on this? Really looking for this solution.

@yhaiovyi
Copy link

It's a dealbreaker for me...

@Mark-Panda

This comment has been minimized.

@tylim88

This comment has been minimized.

@cudba
Copy link

cudba commented Nov 30, 2020

until this is part of the prisma cli, we extracted a small script which we use internally into this tiny cli prisma-merge. its nothing fancy but works for us currently. feel free to use it or copy the source and tailor it to your needs.

@hgezim
Copy link

hgezim commented Jan 2, 2021

Ideally, I'd like my models to live near their/in modules in Nest.

@slinden2
Copy link

slinden2 commented Jan 2, 2021

Would be a nice feature. A single file is not maintainable.

@matthewmueller matthewmueller added the domain/schema Issue in the "Schema" domain: Prisma Schema, Introspection, Migrations etc. label Jan 14, 2021
@matthewmueller matthewmueller added domain/client Issue in the "Client" domain: Prisma Client, Prisma Studio etc. and removed domain/schema Issue in the "Schema" domain: Prisma Schema, Introspection, Migrations etc. labels Jan 25, 2021
@kevinvdburgt
Copy link

kevinvdburgt commented Jan 26, 2021

Please, don't be hostile.

I would love to see this feature as well coming to Prisma 2. There is a workaround (we used in some projects) which might help:

cat *.part.prisma > schema.prisma
yarn prisma generate

@yazer79
Copy link

yazer79 commented Feb 6, 2021

I think this is a "basic" feature for any project. Many months passed now, and there is no update on this.
I can't believe Iit is so hard to make a modular schema file and that would actually take almost a year and no progress on this basic matter

@paulosalvatore
Copy link

paulosalvatore commented Feb 7, 2021

I agree that this is really needed, but npx prisma-merge provides a great workaround.

Thank you guys and looking forward on this implementation :)

@ncirkel
Copy link

ncirkel commented Feb 7, 2021

Good workarounds exist and have been proposed, but one basic modular use case that is holding me back is this one:

Module A:

type Story {
  id: ID!
}

Module B:

type Product {
  id: ID!
  relatedStories: [Story!]!
}

extend type Story {
  relatedProducts: [Product!]!
}

This wasn't possible in Prisma 1 either, but it would be amazing if the Prisma devs could make that happen.

@ChristophDietrich
Copy link

Good workarounds exist and have been proposed, but one basic modular use case that is holding me back is this one:

Module A:


type Story {

  id: ID!

}

Module B:


type Product {

  id: ID!

  relatedStories: [Story!]!

}



extend type Story {

  relatedProducts: [Product!]!

}

This wasn't possible in Prisma 1 either, but it would be amazing if the Prisma devs could make that happen.

This would be very very awesome 👏 👏👏

jkomyno added a commit to prisma/prisma-engines that referenced this issue Apr 8, 2024
* Implement multi-file schema handling in PSL

This commit implements multi-file schema handling in the Prisma Schema Language.

At a high level, instead of accepting a single string, `psl::validate_multi_file()` is an alternative to `psl::validate()` that accepts something morally equivalent to:

```json
{
  "./prisma/schema/a.prisma": "datasource db { ... }",
  "./prisma/schema/nested/b.prisma": "model Test { ... }"
}
```

There are tests for PSL validation with multiple schema files, but most of the rest of engines still consumes the single file version of `psl::validate()`. The implementation and the return type are shared between `psl::validate_multi_file()` and `psl::validate()`, so the change is completely transparent, other than the expectation of passing in a list of (file_name, file_contents) instead of a single string. The `psl::validate()` entry point should behave exactly the same as `psl::multi_schema()` with a single file named `schema.prisma`. In particular, it has the exact same return type.

Implementation
==============

This is achieved by extending `Span` to contain, in addition to a start and end offset, a `FileId`. The `FileId` is a unique identifier for a file and its parsed `SchemaAst` inside `ParserDatabase`. The identifier types for AST items in `ParserDatabase` are also extended to contain the `FileId`, so that they can be uniquely referred to in the context of the (multi-file) schema. After the analysis phase (the `parser_database` crate), consumers of the analyzed schema become multi-file aware completely transparently, no change is necessary in the other engines.

The only changes that will be required at scattered points across the codebase are the `psl::validate()` call sites that will need to receive a `Vec<Box<Path>, SourceFile>` instead of a single `SourceFile`. This PR does _not_ deal with that, but it makes where these call sites are obvious by what entry points they use: `psl::validate()`, `psl::parse_schema()` and the various `*_assert_single()` methods on `ParserDatabase`.

The PR contains tests confirming that schema analysis, validation and displaying diagnostics across multiple files works as expected.

Status of this PR
=================

This is going to be directly mergeable after review, and it will not affect the current schema handling behaviour when dealing with a single schema file.

Next steps
==========

- Replace all calls to `psl::validate()` with calls to `psl::validate_multi_file()`.
- The `*_assert_single()` calls should be progressively replaced with their multi-file counterparts across engines.
- The language server should start sending multiple files to prisma-schema-wasm in all calls. This is not in the spirit of the language server spec, but that is the most immediate solution. We'll have to make `range_to_span()` in `prisma-fmt` multi-schema aware by taking a FileId param.

Links
=====

Relevant issue: prisma/prisma#2377

Also see the [internal design doc](https://www.notion.so/prismaio/Multi-file-Schema-24d68fe8664048ad86252fe446caac24?d=68ef128f25974e619671a9855f65f44d#2889a038e68c4fe1ac9afe3cd34978bd).

* chore(prisma-fmt): fix typo

* chore(prisma-fmt): add comment

* chore(prisma-fmt): fix compilation after #4137

---------

Co-authored-by: Alberto Schiabel <[email protected]>
Co-authored-by: jkomyno <[email protected]>
jkomyno added a commit to prisma/prisma-engines that referenced this issue Apr 8, 2024
* Implement multi-file schema handling in PSL

This commit implements multi-file schema handling in the Prisma Schema Language.

At a high level, instead of accepting a single string, `psl::validate_multi_file()` is an alternative to `psl::validate()` that accepts something morally equivalent to:

```json
{
  "./prisma/schema/a.prisma": "datasource db { ... }",
  "./prisma/schema/nested/b.prisma": "model Test { ... }"
}
```

There are tests for PSL validation with multiple schema files, but most of the rest of engines still consumes the single file version of `psl::validate()`. The implementation and the return type are shared between `psl::validate_multi_file()` and `psl::validate()`, so the change is completely transparent, other than the expectation of passing in a list of (file_name, file_contents) instead of a single string. The `psl::validate()` entry point should behave exactly the same as `psl::multi_schema()` with a single file named `schema.prisma`. In particular, it has the exact same return type.

Implementation
==============

This is achieved by extending `Span` to contain, in addition to a start and end offset, a `FileId`. The `FileId` is a unique identifier for a file and its parsed `SchemaAst` inside `ParserDatabase`. The identifier types for AST items in `ParserDatabase` are also extended to contain the `FileId`, so that they can be uniquely referred to in the context of the (multi-file) schema. After the analysis phase (the `parser_database` crate), consumers of the analyzed schema become multi-file aware completely transparently, no change is necessary in the other engines.

The only changes that will be required at scattered points across the codebase are the `psl::validate()` call sites that will need to receive a `Vec<Box<Path>, SourceFile>` instead of a single `SourceFile`. This PR does _not_ deal with that, but it makes where these call sites are obvious by what entry points they use: `psl::validate()`, `psl::parse_schema()` and the various `*_assert_single()` methods on `ParserDatabase`.

The PR contains tests confirming that schema analysis, validation and displaying diagnostics across multiple files works as expected.

Status of this PR
=================

This is going to be directly mergeable after review, and it will not affect the current schema handling behaviour when dealing with a single schema file.

Next steps
==========

- Replace all calls to `psl::validate()` with calls to `psl::validate_multi_file()`.
- The `*_assert_single()` calls should be progressively replaced with their multi-file counterparts across engines.
- The language server should start sending multiple files to prisma-schema-wasm in all calls. This is not in the spirit of the language server spec, but that is the most immediate solution. We'll have to make `range_to_span()` in `prisma-fmt` multi-schema aware by taking a FileId param.

Links
=====

Relevant issue: prisma/prisma#2377

Also see the [internal design doc](https://www.notion.so/prismaio/Multi-file-Schema-24d68fe8664048ad86252fe446caac24?d=68ef128f25974e619671a9855f65f44d#2889a038e68c4fe1ac9afe3cd34978bd).

* WIP(schema-wasm): Support schema split into multiple files

* Reformat support (psl crate)

* Add multifile reformatting tests

* Clippy

* feat(prisma-fmt): addd support for mergeSchemas, expose functions to prisma-fmt-wasm

* chore(prisma-fmt): removed unused function

* chore: fix typo

Co-authored-by: Serhii Tatarintsev <[email protected]>

* feat(prisma-fmt): apply validation to merge_schemas

* chore(prisma-fmt): update unit test

* chore: fix bad merge

* chore: fix tests

---------

Co-authored-by: Tom Houlé <[email protected]>
Co-authored-by: Alberto Schiabel <[email protected]>
Co-authored-by: jkomyno <[email protected]>
@dashaomai
Copy link

Can this resolve the problem?

Prisma-MultiSchema

@Messhias
Copy link

Messhias commented Apr 9, 2024

Can this resolve the problem?

Prisma-MultiSchema

It's solve, but this is the horrible thing about the JS ecosystem; everything it's a lot bundle of packages. In my opinion the Prisma developer should take your package and implement the code into the prisma. Or, you create a pull request that envolve the package.

Personally I'll wouldn't install more JS packages to solve an issue of an JS package. If you think about it, is something quite bad for community.

@nlynzaad
Copy link

nlynzaad commented Apr 9, 2024

looking at PR 4243 and PR 4787 it looks like we may soon have native support in prisma.

@janpio
Copy link
Contributor

janpio commented Apr 9, 2024

Well spotted @nlynzaad, we have indeed started work on this functionality.
We'll post an update here when there is something ready to play and test with.

mathiasberggren added a commit to mathiasberggren/streaming-subscription that referenced this issue Apr 9, 2024
mathiasberggren added a commit to mathiasberggren/streaming-subscription that referenced this issue Apr 13, 2024
mathiasberggren added a commit to mathiasberggren/streaming-subscription that referenced this issue Apr 19, 2024
mathiasberggren added a commit to mathiasberggren/streaming-subscription that referenced this issue Apr 19, 2024
mathiasberggren added a commit to mathiasberggren/streaming-subscription that referenced this issue Apr 20, 2024
mathiasberggren added a commit to mathiasberggren/streaming-subscription that referenced this issue Apr 23, 2024
@divmgl
Copy link

divmgl commented Apr 24, 2024

#2377 (comment) No need for this. I didn't see anything too unreasonable.

Looking forward to this feature. It'd be nice if we could target a folder and all of the schema files within that folder get picked up. Similar to how HCL with Terraform works.

prisma generate --schema ./schema
# Targets the entire ./schema folder, picks up all schema files within it Terraform style

@MrSharpp

This comment was marked as off-topic.

@mdarifulislamroni521

This comment was marked as off-topic.

Weakky pushed a commit to prisma/prisma-engines that referenced this issue May 16, 2024
This commit implements multi-file schema handling in the Prisma Schema Language.

At a high level, instead of accepting a single string, `psl::validate_multi_file()` is an alternative to `psl::validate()` that accepts something morally equivalent to:

```json
{
  "./prisma/schema/a.prisma": "datasource db { ... }",
  "./prisma/schema/nested/b.prisma": "model Test { ... }"
}
```

There are tests for PSL validation with multiple schema files, but most of the rest of engines still consumes the single file version of `psl::validate()`. The implementation and the return type are shared between `psl::validate_multi_file()` and `psl::validate()`, so the change is completely transparent, other than the expectation of passing in a list of (file_name, file_contents) instead of a single string. The `psl::validate()` entry point should behave exactly the same as `psl::multi_schema()` with a single file named `schema.prisma`. In particular, it has the exact same return type.

Implementation
==============

This is achieved by extending `Span` to contain, in addition to a start and end offset, a `FileId`. The `FileId` is a unique identifier for a file and its parsed `SchemaAst` inside `ParserDatabase`. The identifier types for AST items in `ParserDatabase` are also extended to contain the `FileId`, so that they can be uniquely referred to in the context of the (multi-file) schema. After the analysis phase (the `parser_database` crate), consumers of the analyzed schema become multi-file aware completely transparently, no change is necessary in the other engines.

The only changes that will be required at scattered points across the codebase are the `psl::validate()` call sites that will need to receive a `Vec<Box<Path>, SourceFile>` instead of a single `SourceFile`. This PR does _not_ deal with that, but it makes where these call sites are obvious by what entry points they use: `psl::validate()`, `psl::parse_schema()` and the various `*_assert_single()` methods on `ParserDatabase`.

The PR contains tests confirming that schema analysis, validation and displaying diagnostics across multiple files works as expected.

Status of this PR
=================

This is going to be directly mergeable after review, and it will not affect the current schema handling behaviour when dealing with a single schema file.

Next steps
==========

- Replace all calls to `psl::validate()` with calls to `psl::validate_multi_file()`.
- The `*_assert_single()` calls should be progressively replaced with their multi-file counterparts across engines.
- The language server should start sending multiple files to prisma-schema-wasm in all calls. This is not in the spirit of the language server spec, but that is the most immediate solution. We'll have to make `range_to_span()` in `prisma-fmt` multi-schema aware by taking a FileId param.

Links
=====

Relevant issue: prisma/prisma#2377

Also see the [internal design doc](https://www.notion.so/prismaio/Multi-file-Schema-24d68fe8664048ad86252fe446caac24?d=68ef128f25974e619671a9855f65f44d#2889a038e68c4fe1ac9afe3cd34978bd).
@aseemk
Copy link

aseemk commented May 17, 2024

Well spotted @nlynzaad, we have indeed started work on this functionality. We'll post an update here when there is something ready to play and test with.

This is awesome @janpio, thank you! Our own schema file is at almost 1,500 LOC now, so we'd love a split. =)

If it's helpful from a design perspective, just wanted to request the ability for schema files to be split up across separate folders too, not necessarily all in one. We organize our codebase how the OP here described:

flexible integration with certain architectures, i.e. each module has its own self-contained logic including its schema

(And we've been finding that extremely nice and helpful.)

Thanks again!

@darkartur
Copy link

No with react native support this makes even more sense if someone decides to share schema between backend and react native app

@dolapo1
Copy link

dolapo1 commented May 30, 2024

Create a folder called models in your prisma folder, then add our files to it:

mkdir prisma/models
touch prisma/models/config.prisma
touch prisma/models/user.prisma
touch prisma/models/post.prisma

config.prisma

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

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

user.prisma

model User {
  id        Int      @id @default(autoincrement())
  username  String   @unique
  email     String   @unique
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
  posts     Post[]
}
post.prisma
model Post {
  id        Int      @id @default(autoincrement())
  title     String
  content   String
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
  author    User     @relation(fields: [authorId], references: [id])
  authorId  Int
}

The merging step.
This is where the magic happens, thanks to a single command, we will merge our models into the main schema.prisma file:

cd ./prisma/models && rm -rf ../schema.prisma && cat *.prisma >> ../schema.prisma && cd .. && prisma format
Breakdown of the command:

We change the current dir

cd ./prisma/models
We delete the content of the main file

rm -rf ../schema.prisma
We add the content of our models to the main file

cat *.prisma >> ../schema.prisma
We format and fix errors

prisma format You can add the following to your package.json so that you can just run npm run gen:schema:

"gen:schema": "cd ./prisma/models && rm -rf ../schema.prisma && cat *.prisma >> ../schema.prisma && cd .. && prisma format",
After this step, just run

npx prisma migrate dev --name init

@dolapo1
Copy link

dolapo1 commented May 30, 2024

I found this somewhere.

@nlynzaad
Copy link

nlynzaad commented May 31, 2024

seems like the wait is just about over PR
X (Twitter) Teaser

Huge thanks to all the developers for their efforts on this. Been stalking the pull requests on this and it seems to have been quite the undertaking

@Jolg42 Jolg42 added this to the 5.15.0 milestone Jun 4, 2024
@janpio
Copy link
Contributor

janpio commented Jun 4, 2024

Hey, we just released support for multiple-file Prisma Schema setups! It is behind the prismaSchemaFolder preview feature:

Please try it out and leave feedback in this discussion: #24413

@prisma prisma locked as resolved and limited conversation to collaborators Jun 4, 2024
@janpio janpio added the status/is-preview-feature This feature request is currently available as a Preview feature. label Jun 5, 2024
@apolanc apolanc removed this from the 5.15.0 milestone Jun 6, 2024
@janpio janpio removed their assignment Nov 1, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.