-
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
Custom data types for fields #5039
Comments
I would also very much appreciate if you implemented this feature. I have various use cases for this feature but the most pressing one at the moment is this:
|
+1 for custom types. Would really improve schema design! |
This isn't something I've felt the need for before, but as soon as I read your suggestion I saw a lot of solutions to some pretty annoying problems I have today. It seems to me that this and #3394 has a little bit of common ground. Both modify the response after the data has been read from the database, but this is more of a read/write while the virtual fields would (probably) be read only. Perhaps it's insignificant. Secondly, if you're daring enough you could probably already do this with middleware. They can be expensive on performance if used incorrectly, but sounds like just the right tool if anyone need to solve this urgently. |
Custom serialization and deserialization into/out of javascript objects would be fantastic. TypeORM has an analogous feature called a "transformer". I've used TypeORM in the past with the Postgres UUID type to remove dashes from the UUID in an application that didn't support them. Postgres treats all UUIDs as integers internally, so the representation on the wire and in app code is somewhat arbitrary, and having the ability to customize that by removing dashes, forcing uppercase/lowercase, using a BigInt instead of a string, or even something like Shakespearean UUIDs, would be handy. Another use case might be mapping TC39's Temporal date and time values in application code to/from database types. For example, storing a civil date in a database as an ISO8601 string in a TEXT column (e.g. the string "2022-01-01"), but using a Temporal.PlainDate in the prisma-generated client code, with custom serialization/deserialization. |
+1 for custom types, this will helps on the transformers cases, working with pipes to control field transformation, currently I am accepting workarounds for it :) |
+1 |
An other common use case: File field. A file is saved on a third party service on create/update and the pathname is persisted in the database. |
+1 |
Similar use cases:
|
This is one of the reasons why I haven't switched over from Sequelize because I can at least create custom types there such as I have a Snowflake custom type that transforms and I have a method where if it is a primary key with auto increment that it uses a third party library to generate the ids etc. So it would be nice to be able to not only be able to create the custom types but be able to create specific rules that would run through a transformer for example. "if I specify auto increment with a custom type, I can then hook in the third party that generates these "autofields". |
+1, bump this. we need this very much.
so, one day, if we need to move from mysql to other engine. |
+1 This would make dealing with Snowflakes(Datatype) a lot easier |
I would love this as well! As an example, we currently use MongoDB and are migrating to Prisma/Postgres. In our current types we have To be clear, we are not asking for a way to do any serialising/deserialising. We only want to use a subset of the I'm not sure if that's exactly what being asked here, so maybe I should open a separate issue for this... |
Another nudge on this one. In my case I'd love to have typed identifiers for each of my entities:
So when defining the prisma model, I'd like to not only alias a database type, but also customize the generated native type. I recognize that this becomes complicated as the generated types would either need to include the above type definition or import it (probably the former). |
Any news from maintainers on the matter? |
No. The feature request is being tracked and the issue might be prioritized in the future. Right now it is not. |
In my honest opinion, an ORM not prioritizing a vital issue like this is akin to shooting oneself in the foot. There are a lot of things an ORM needs to get right before considered production ready and this is one of them. It's currently impossible to work with non-uuid IDs like nanoid, ksuid, xid, ulid etc... because of this issue. |
+1 on this issue too In my case I would like to use Phantom Types to narrow ID types, so I get type errors when trying to assign a postId to a userId, when both models have a I'll probably end up creating custom types on top of Prisma ones, but it would be nice to accomplish this natively with Prisma // Emitted types from Prisma
type UserPrisma = {
id: string
name: string
}
type PostPrisma = {
id: string
title: string
}
type ID<Type extends string | number, Model> = Type & { __idFor: Model }
type User = Omit<UserPrisma,'id'> & {
id: ID<UserPrisma['id'], User>
}
type Post = Omit<PostPrisma,'id'> & {
id: ID<PostPrisma['id'], Post>
}
const userId = 'user_1' as User['id']
const findPost = (id: Post['id']): Post => {
return { id, title: 'Phantom Types' }
}
findPost(userId) But this doesn't work very well bc Prisma query outputs are the "basic" ones |
I'm surprised that Prisma doesn't have this feature because most ORMs I've used have it. Anyway, my solution for now is to use the Repository pattern so that I can de-serialize the data in a single place and consume it in my application, then also serialize it for storage in a single place as well. It's a little more work than using the ORM directly but the only way I could think of that doesn't require complicated gymnastics. |
Drizzle has this now and it's really nice. Prisma client extensions work well for changing the result of the output value, but not really great for writes. API proposalIt could be a part of Prisma client extensions // create a custom type
const dateToTemporalInstant = Prisma.createCustomType<Date, Temporal.Instant>({
encode: (value) => toInstant(value),
decode: (value) => toJsDate(value),
});
// add it to `Post.createdAt` + `Post.updatedAt`
export const prisma = client.$extends({
customTypes: {
post: {
createdAt: dateToTemporalInstant,
updatedAt: dateToTemporalInstant,
},
},
}); |
Hi, our company is moving from PHP to Node ecosystem and I am impressed by this project. Great work and great thinking especially! <3
Problem
However, there is one thing that feels natural to me when mapping raw rows from database to sophisticated and type-safe objects: custom data types. I spent the last three hours reading Prisma's manual and googling related issues but I don't see any open issue about this topic.
Use cases:
I found issues related to unsupported data types like Support a Date Scalar Type #255 or Add support for 64-bit integers #5001.
In our application we use data types like currencies, IBANs, time zone offsets, IP addresses, EANs, locale territories, VAT numbers, and many others that are usually stored as simple chars/varchars in the database, but are represented with a more refined data type in the application (like some class instance).
You might want to use better alternatives for TIMESTAMP or DATETIME types than JavaScript's native Date class and map such database types to eg. a Luxon instance.
Suggested solution
All three of these cases can be handled by allowing to define a custom column data type that:
In PHP we use Doctrine and this is what I have in mind: https://www.doctrine-project.org/projects/doctrine-orm/en/2.7/cookbook/custom-mapping-types.html . (Yes, Doctrine is a full-blown ORM library but IMO this idea can be used nevertheless.)
Thanks to this feature people would be able to create own custom mappings for column types that have not been supported by Prisma yet (as a temporary workaround), as well as use some eg. "IP address" type without the need for explicit in-application mapping (from the object returned from Prisma to object with better data types) for better developer experience.
The closest ideas I found: #446 (comment) (if you add the (de)serialization mapping functions), #3618 (could be solved by custom data types), prisma/specs#119 (replaced by #446 which I don't think is the same).
What we would need:
vatNumber
type serialization and deserialization functions to Prisma's attributes mapping functionality.The expected behavior is that when reading some company row from the database, the
vatNumber
attribute in the object is going to be some eg.VatNumber
class instance (as implemented by the deserialization function). Also, when inserting/updating I am going to be able to use theVatNumber
instance directly without needing to serialize it to a string at first.So what do you think? Is it something that is completely out of the scope of this project? Or would you consider this to be something useful? Or is there some other issue with the same idea that I simply missed?
Thanks! :)
PS: The first thing I naturally tried to do was to use the
VatNumber
type in the schema to see what happens and I got this error:That has got me thinking: what did you mean by this "custom type" in the error message? ;-)
The text was updated successfully, but these errors were encountered: