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
Preview feature feedback: Extended where unique #15837
Comments
The link to docs is not working 🥲 |
It will be as soon as the feature is actually released. Just a bit more patience and you'll have it 🙈. The documentation will be referred to from the release notes as well. |
Just noticed that optimistic concurrency is closed as implemented by this feature (yay!). Not clear from this issue how to implement, probably just a docs issue? |
@capaj Docs link should also work now. |
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
"The preview feature "extendedWhereUnique" is not known"Edit: Solved by reinstalling It works but my VSCode complains with I updated my packages using Update: you can ignore this, I did the package.json etc
"@prisma/client": "^4.5.0",
"prettier-plugin-prisma": "^4.4.0",
"prisma": "^4.5.0",
The feature is very useful. Not sure if it's better -- maybe it should be a distinct conscious choice when you narrow the selection? await prisma.article.update({
where: {
id: 5,
$narrow: { version: 1 },
},
data: { /* ... */ }
}) Furthermore - I've always found it a bit confusing that |
This comment was marked as outdated.
This comment was marked as outdated.
@KATT We designed a very similar API while researching the topic. Here were the 3 designs we had: 1) Adapt WhereUniqueInputawait prisma.user.update({
where: { email: "alice@prisma.io", OR: [{ name: "Alice" }, { name: "Bob" }] }
data: { email: "alice2@prisma.io" }
}) 2) Nested if / where / filterawait prisma.user.update({
where: { email: "alice@prisma.io", _if: { OR: [{ email: "" }], isDeleted: false }},
data: { email: "alice2@prisma.io" },
}) 3) Additional if / where / filterawait prisma.user.update({
where: { email: "alice@prisma.io" }, // required
data: { email: "alice2@prisma.io" },
if: { isDeleted: false } // optional
}) You can see how design 2) is very similar to yours. We ultimately decided to go with design 1) because 2) and 3) felt confusing from a SQL perspective. There's no such thing as As for design 3), it was too hard to integrate with our existing API without adding lots of union input types. One downside of the current design is how it clutters the autocompletion and makes it hard to find the unique fields that need to be set. On the other hands, it's very transparent wrt. how SQL works. Let us know what you all think 🙏 |
@floelhoeffel Thanks for adding this feature!
Running the above, produces the following error:
Is my scenario currently possible to achieve? |
Hey @YaakovR, Good catch and apologies, this is an oversight from myself. Your use case should work but it's currently not supported. We'll add that for the next Prisma release. To be clear:
Adding a |
Thanks @Weakky! That makes sense. I'll look out for the next release! |
This is awesome! Are |
@Weakky I'm also seeing this error after bumping to
"dependencies": {
"@prisma/client": "4.5.0",
},
"devDependencies": {
"prisma": "4.5.0",
}, yarn prisma --version
prisma : 4.5.0
@prisma/client : 4.5.0
Current platform : darwin-arm64
Query Engine (Node-API) : libquery-engine 0362da9eebca54d94c8ef5edd3b2e90af99ba452 (at node_modules/prisma/node_modules/@prisma/engines/libquery_engine-darwin-arm64.dylib.node)
Migration Engine : migration-engine-cli 0362da9eebca54d94c8ef5edd3b2e90af99ba452 (at node_modules/prisma/node_modules/@prisma/engines/migration-engine-darwin-arm64)
Introspection Engine : introspection-core 0362da9eebca54d94c8ef5edd3b2e90af99ba452 (at node_modules/prisma/node_modules/@prisma/engines/introspection-engine-darwin-arm64)
Format Binary : prisma-fmt 0362da9eebca54d94c8ef5edd3b2e90af99ba452 (at node_modules/prisma/node_modules/@prisma/engines/prisma-fmt-darwin-arm64)
Format Wasm : @prisma/prisma-fmt-wasm 4.5.0-43.0362da9eebca54d94c8ef5edd3b2e90af99ba452
Default Engines Hash : 0362da9eebca54d94c8ef5edd3b2e90af99ba452
Studio : 0.476.0 Working with the schema (i.e. running Environment variables loaded from .env
Prisma schema loaded from src/server/db/schema.prisma
Datasource "db": PostgreSQL database "betterform", schema "public" at "localhost:5832"
Already in sync, no schema change or pending migration was found.
✔ Generated Prisma Client (4.5.0 | library) to ./node_modules/@prisma/client in 76ms
Schema validation error - Error (query-engine-node-api library)
Error code: P1012
error: The preview feature "extendedWhereUnique" is not known. Expected one of: referentialIntegrity, interactiveTransactions, fullTextSearch, fullTextIndex, tracing, metrics, orderByNulls, filteredRelationCount, fieldReference
--> schema.prisma:8
|
7 | provider = "prisma-client-js"
8 | previewFeatures = ["extendedWhereUnique"]
|
Validation Error Count: 1
[Context: getDmmf]
Prisma CLI Version : 4.3.1 |
Hey @jacobchrismarsh, Batching is currently broken in 4.5.0. However, we have a PR that will land next release which will fix that. Docs will be updated accordingly. TLDR is: The batching will still work if you only use unique & non-unique scalar fields of the model you're querying and if the filter applied is If you use any boolean operators, relation filters or any other filters than equal on a scalar field, then we will not try to batch @SamuelMS Are you sure your Prisma CLI is not globally installed and you haven't forgotten to update it ? |
@Weakky Hmm, fairly certain – it's being installed in the repo and this is what I get from
|
@SamuelMS The end of your output shows that this is somehow running |
Apologies for the false promise @YaakovR 🙈, we couldn't get the It should be in the next release though, bear with us 🙏 |
I was wondering about that. Thanks @Weakky for clarifying. |
Does upsert support boolean operators even though they use the same WhereUnique type than update?
|
@Weakky what about having a different TS return typing when a My use case is implementing access control policies at the query level (e.g. something like Something like this I think could be ideal, preserving the data-model contract and introducing optionality:
A few of us have run into this issue here: #16049 |
Love this feature! Thank you Prisma team! |
Adding a feedback to the discussion, I'm encountering a trouble trying to filter like model User {
id String @id @default(dbgenerated("gen_random_uuid()")) @map("id") @db.Uuid()
authAccount String? @unique
} Trying to make a safe atomic update : await prismaClient.user.update({
where: { id: userId, authAccount: null },
data: { authAccount: createdAuthAccount.id },
}) I'm getting a Typescript error on
Temporary workaround : wrap in a dumb await prismaClient.user.update({
where: { id: userId, OR([{ authAccount: null }]) },
data: { authAccount: createdAuthAccount.id },
}) |
Hey @cyrilchapon, That's an interesting problem that we haven't considered in our design and one that'll be hard/convoluted to solve with the current approach. The reason you can't filter However, with the extension of unique The issue in your case, is that we should make We're unfortunately not in a position to make that happen atm though. It would be possible from a typing perspective, but harder from a query validation perspective. We validate queries against a schema, similar to GraphQL, and that schema does not support "conditional typings" on fields. The good news is, there's a simple workaround. The bad news is, it's confusing. I'll have a chat with the team about that. |
Hey @Weakky , That's what I guessed. Well; to circumvent this, and since the "dumb AND/OR workaround" works; I feel like arguing the syntax could be reworked in a less-sexy but way-easier-to-type-and-parse : prismaClient.someModel.update({
where: {
// unique fields at the root,
// easy to parse-and-type
id: 2,
// Non unique ones wrapped in a key
// (could be renamed ^^)
NON_UNIQUE: {
someNonUniqueField: null
}
},
}) or even prismaClient.someModel.update({
where: {
// unique fields at the root,
// easy to parse-and-type
id: 2,
},
// Non unique ones wrapped in an entire clause
// (could also be renamed ^^)
atomicUpdateWhere: {
someNonUniqueField: null
}
}) |
Hello. I didn't read much of everything but it's actually crazy of what’s going on. I'm trying to upsert oauth2 tokens CREATE TABLE `rider_tokens` (
`id` int(10) UNSIGNED NOT NULL,
`rider_id` mediumint(8) UNSIGNED NOT NULL,
`access_token` text COLLATE utf8_unicode_ci NOT NULL,
`refresh_token` text COLLATE utf8_unicode_ci NOT NULL,
`expiration` datetime DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
ALTER TABLE `rider_tokens`
ADD PRIMARY KEY (`id`),
ADD KEY `rider_id` (`rider_id`);
ALTER TABLE `rider_tokens`
MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT;
ALTER TABLE `rider_tokens`
ADD CONSTRAINT `rider_tokens_ibfk_1` FOREIGN KEY (`rider_id`) REFERENCES `riders` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
COMMIT; rider_id is an index and id is an auto increment primary key. I never need to use id really, it’s just there for indexing perposes and rider_id is what will always be used. async saveRiderTokens(rider_id: number, data: any): Promise<any> {
return this.prisma.rider_tokens.upsert({
where: { // here
rider_id,
},
update: {
access_token: await this.hash(data.access_token),
refresh_token: await this.hash(data.access_token),
},
create: {
rider_id,
access_token: await this.hash(data.access_token),
refresh_token: await this.hash(data.refresh_token),
},
});
} it doesn't allow me to do this because it expects id to always be there. error: src/services/auth/auth.service.ts:65:4 - error TS2322: Type '{ rider_id: number; }' is not assignable to type 'rider_tokensWhereUniqueInput'.
Type '{ rider_id: number; }' is not assignable to type '{ id: number; } & { id?: number; AND?: Enumerable<rider_tokensWhereInput>; OR?: Enumerable<rider_tokensWhereInput>; ... 5 more ...; riders?: (Without<...> & ridersWhereInput) | (Without<...> & RidersRelationFilter); }'.
Property 'id' is missing in type '{ rider_id: number; }' but required in type '{ id: number; }'.
65 where: {
~~~~~
node_modules/.prisma/client/index.d.ts:41766:5
41766 where: rider_tokensWhereUniqueInput
~~~~~
The expected type comes from property 'where' which is declared here on type '{ select?: rider_tokensSelect; include?: rider_tokensInclude; where: rider_tokensWhereUniqueInput; create: (Without<...> & rider_tokensUncheckedCreateInput) | (Without<...> & rider_tokensCreateInput); update: (Without<...> & rider_tokensUncheckedUpdateInput) | (Without<...> & rider_tokensUpdateInput); }' |
Thank you everyone for the feedback 🙌🏼 We’re excited to announce the We first introduced this feature in version 4.5.0 to add support for non-unique columns inside For example, consider the following model: model Article {
id Int @id @default(autoincrement())
content String
version Int
} |
Please use this issue to share any feedback about the
extendedWhereUnique
functionality released in v4.5.0.Documentation can be found here.
If you encounter a bug, please open a bug report in this repo.
Many thanks 👏🏻 from the Prisma team.
The text was updated successfully, but these errors were encountered: