-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Reuse collections of fields inside models #2371
Comments
Hi, Thanks for reporting this! It has already been reported before, so I am going to close this as a duplicate of #1291 |
#1291 is about importing models. This request is about being able to reuse collections of fields inside models. That is quite different and I think justifies a separate issue @pantharshit00. @richardwardza Updating the title of this issue might help to make the feature more precise 👍 |
@janpio I was referring to extending part of that FR: import "dependency/prisma/core.prisma"
extend model Post {
title String @pg.varchar(50)
slug String
} This is essentially the same thing as this feature request but with a different syntax. |
Thanks @janpio. I've updated the title - |
Looks like inspiration could be taken from |
Alternate proposal from #3520 (comment) abstract model Basics {
id Int @id @default(autoincrement())
updatedAt DateTime @updatedAt
createdAt DateTime @default(now())
}
model User extends Basics {
email String @unique
}
model Task extends Basics {
title String
} |
Yes, that follows the inheritance pattern over a composition one. |
I think this approach is fine either if there's a way to extend from multiple models. |
In GQL there exists an
|
I would highly favour some kind of |
Any input on this from the prisma team? Im working with a lot of tables that all have the same general meta data columns, and other share type specific columns. Typing out every new model as a whole is tedious and I big detractor in value from things like TypeORM which allow Entity inheritance, extension, and embedding. I am a fan of the interface/implements and abstract/extends approach above (both appear very similar assuming the extends allows extending multiple abstract models), but I really like the value in the OP for things like embedded objects. For example: collection Base {
id String @id @default(cuid())
createdAt DateTime @default(now())
createdBy String
}
collection Address {
street1 String
street2 String?
city String
state String
zip String
}
model Building{
//...other fields
@collection('Base')
@collection('Address', embed)
//@collection( CollectionName: string, InheritType: 'spread' | 'embed' = 'spread')
} Would result in tables field structure and interface below: TABLE Building {
//... other columns
id uuid PRIMARY KEY NOT NULL;
createdAt timestamptz NOT NULL;
createdBy uuid NOT NULL;
address_street1 varchar NOT NULL;
address_street2 varchar NULL;
address_city varchar NOT NULL;
address_state varchar NOT NULL;
address_zip varchar NOT NULL;
} interface Building {
//... other columns
id: string;
createdAt: Date;
createdBy: string; //Expanded to user if relationship created in model
address: {
street1: string;
street2?: string;
city: string;
state: string;
zip: string;
}
} I assume the interface/inherit or abstract/extends style would auto spread all inherited fields directly on to the model. The @collection decorator could allow for some very powerful customization and code reusability. |
This would be awesome to have. Is there a way the community can vote on prioritized features? Wouldn't want this to get lost in the noise. |
Leave a 👍 reaction on the original issue - we use that to inform our internal prioritization. |
An alternative approach:
If I could only choose one thing, "fragments" or "inheritance", I'd much prefer fragments. The reason is that fragments are simply "expanding" the schema during a preprocessing step, whereas "inheritance" (via extends) implies that something much more complicate is going on with the database (even if it's not). Also, inheriting a model happens at the top-level, and is all-or-nothing, whereas multiple includes/partials/fragments can be injected into a model wherever you want them to be. I choose the syntax in my example since it's easy to parse and disambiguate that syntax from other existing features, and it will allow the syntax to play nicely with fields that were defined inline. FWIW, IMHO the hard part is making a decision on the syntax. Once that decision is made, the implementation should be pretty simple, and could be implemented without having to re-write the current parser since we're just "expanding" the schema. I'd be happy to do a PR, or write some code that accomplishes what I suggested (or what someone else suggested) if you'd consider adding this as a pre-processing step. Which brings up one more possibility: you could add support for the |
FWIW, I considered implementing something like this either as a VS Code extension or as a custom script in our build step. But I'd probably need to fork the syntax highlighter too so we could edit the schema without In the meantime as you consider this, I created this pre-processor after posting my last comment, as a proof of concept: https://gist.github.com/jonschlinkert/55a3f68ad5eb77c4a0b77e24a275f04a IMHO, validation should not be done in this step, since the parser already does validation. It would make more sense to simply "expand" the schema, and then run the parser and provide feedback at that stage. |
I made a simple CLI tool called prisma-compositor that merges multiple prisma schema files from an input directory and allows you to use fragments.
Installation Usage |
@kerimcharfi I like that spread syntax a lot! Better than the syntax I suggested. |
Would love to have something like this. For me also composition > inheritance. |
Any update of this? 😞 |
Why is this fundamental feature not in this ORM? |
Short answer: Because we are busy building other fundamental features that can not be worked around by copy pasting a few fields around. As soon as we have capacity, we will take a look at this and design and implement a solution. |
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
There's also a tool called zenstack that allows abstract/extends model inheritance. The only thing is the abstract models basically just have their fields copied over into their child models so they never get their own dedicated typescript types. It would be great to see this integrated into prisma but with an option to generate dedicated types for the base models. Also, it would be super useful to see the inheritance structure reflected on the typescript side, but I understand this is most likely not possible because the generated types are just types and not interfaces or classes. |
Love zenstack, but I think a fragment implementation would be cooler |
To take this one step further... I have a similar use case where each of my models contains a createdById and a modifiedById. Each should automatically be populated by a user ID from the application. So in addition to just including the fields as part of the model, I'd love to be able to use some kind of global variable or function in my application (Remix, but same concept for any stack) to auto-populate that value - something like a custom function, but also part of the EXTENDS approach. Each "create" and "update" function automatically grabs a value via logic that I specify in some kind of central location - a function, etc. |
Dear all, again, i would like to throw in All the best |
Any News ? |
+1 |
The docs are already outdated :/ |
Problem
I have a number of models in my schema and most of them include the following 4 fields:
It would be great if this could be created as a collection in the file and then just that used in the models.
It could also be used to ensure standards are maintained across the various models (like the
StandardId
snippet below)Solution
A solution would be to allow collections in the schema file. Possibly something like:
The text was updated successfully, but these errors were encountered: