-
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
Add option to skip unnecessary SELECT
after create()
#4246
Comments
I experience the same for upsert. Business logic removed Code
Logs
|
I am also seeing 2 This should be doable with at most 2 queries, (assuming you want to return the rows values after the const id = 1
const col1 = 'foo'
const col2 = 'bar'
// First query (note: using MySQL syntax)
await client.product.$queryRaw`
INSERT INTO product (id, col1, col2) VALUES (${id}, ${col1}, ${col2})
ON DUPLICATE KEY UPDATE
col1=VALUES(col1)
col2=VALUES(col2)
`
// Second query
const product1 = await client.product.findUnique({where: {id: 1}}) And if you don't want to return the whole row, just omit the second query. |
Is there any movement on this? Not sure if this is as relevant, but those select's (after insert even though I haven't specified a |
Very much in favor of this. I was going to create the issue if it didn't exist. For what it's worth, I like the solution proposed by @ziimakc, but I also don't mind if the default behavior of Until this feature is available, I'll have to resort to (ab)using |
Is there any solution to this , except specifying one field 😐 |
@leoantony72 I just use |
Make it optional plz. Not required in my use case at all. |
Would appreciate an option to remove the unnecessary select |
@matthewmueller In my case where we use Postgres and Row Level Security (RLS), these "unnecessary" selects cause many problems in the flows and constantly require workarounds to bypass RLS. As an example: -- db admin
create table rls_test( id BIGSERIAL PRIMARY KEY);
create policy rls_test_sel_policy on rls_test for select to app using (false);
create policy rls_test_ins_policy on rls_test for insert to app with check (true);
alter table rls_test ENABLE ROW LEVEL SECURITY;
alter table rls_test FORCE ROW LEVEL SECURITY;
-- as user app
insert into rls_test default values; -- works
insert into rls_test default values returning id; -- fails
This is a dummy example (can be solved just with DB Roles) just to demonstrate the issue, as the "returning id" clause violates the select policy. Also in the case of FKs, the I can guess removing these selects may break things in the generic way that Prisma works but in our case this is a functionality problem and not a performance one. |
Additional note: this also applies to Big +1 for this request -- it should be a no-brainer to let users avoid extra queries without having to use an escape-hatch like |
+1 |
+1, this is slowing down my queries, how can I just insert new data without having to select it? Would be nice to see this in the Prisma Roadmap |
+1 for the problems it causes with RLS |
Can you elaborate exactly the problem this causes for RLS? I am not sure I follow. |
@janpio If I have a policy that only allows inserting like this: ALTER TABLE "User" ENABLE ROW LEVEL SECURITY;
ALTER TABLE "User" FORCE ROW LEVEL SECURITY;
CREATE POLICY only_create_no_read ON "User"
FOR INSERT
WITH CHECK (true); a |
To give you a more "real world" scenario: model Organization {
id String @id @default(cuid())
name String @unique
users User[]
}
model User {
id String @id @default(cuid())
name String
organization Organization @relation(fields: [organizationId], references: [id])
organizationId String
} If a user signs up, I would have a logic like this: const user = await prisma.user.create({
data: {
name: "MyUser",
organization: {
create: {
name: "teamlearns",
},
},
},
}); so far so good. Now I am adding RLS. I want that
So I might add something like this CREATE POLICY organization_create_policy ON "Organization"
FOR INSERT
WITH CHECK (true);
CREATE POLICY organization_only_member_policy ON "Organization"
USING (
"Organization"."id" = (
SELECT "User"."organizationId"
FROM "User"
WHERE "User"."id" = current_setting('user.userId', true)::text
)
); which will break the Though, now that I think about it, it probably won't work either way, since organization: {
create: {
name: "teamlearns",
},
}, is probably relying on the @janpio does this make things a bit clearer? |
Yes it does. |
Is there any update on this issue? I don't want to select anything after update. |
+1 on this. Currently I've changed my update to only return one field but that's just a workaround. Often the select is the more costly than the create/update itself. |
Any update on this? |
+1 Relational databases have consistency, its information can almost always be trusted, there's no need to query the database again only to return the same things that were just created |
+1 |
https://dev.to/josethz00/benchmark-prisma-vs-typeorm-3873 Prisma is over 1,000x slower than typeorm on create workloads because of this I would not recommend doing an insert through ORM, especially for logs |
I wish I could skip the |
+1 Not yet on the roadmap? |
as a workaround we could use createmany, right? |
For a current scenario I've also switched to using A global setting to disable this behaviour would also be nice, instead of a per query solution. IMO it's bad practice to always do an extra select. |
@jamiter I've tried The most ridiculous thing happens when the model has a self-relation, it will select 3 times before the I'm grateful that Prisma saved us a lot of time for rapid development, but I really wish its developers could have more attention on improving the SQL level logics. In my understanding, being an ORM means you have the best practices of all kinds of stuff related to SQL and database, that's the reason for the community to choose you in the long run. |
@reorx Totally agree with you. (Off-topic ranting below) There are many unsolved issues with many votes and requests but no developer has been participating in. The only comment you may get is some product manager asking what the real world scenarios you are facing and no response anymore. Based on the current roadmap, they were spending most of time working on improving the performance for serverless and data proxy product but ignoring the basic SQL features and bugs. I understand that they have their own business plan and have to focus on it. And sometimes I really wanted to help but don't know writing rust. I appreciate the brilliant DX of Prisma but just keep getting blocked by issues like this for years. Don't know if there's an alternative ORM to try. :( |
This is likely going to be an unsatisfying recommendation but all those who have felt the pain for long enough will agree - just use a query builder. Knex is great and while there's marginally more boilerplate, it's easy and extensible. I use Knex + sql-ts + dmate and I've never looked back (to Prisma.) |
@Songkeys SQL query builder is the thing! As @coryvirok also mentioned. I had the experience where I migrate from gorm to sqlx when writting go applications, and I was more than happy about the result. Having control over what SQL is executed is vital in serious use cases such as trading or payment systems. I havn't try Knex or Kysely because I was not quite familar with TypeScript and the timeline was urgent, but I think it's fairly the same comparing with sqlx in Go. Both Go and TypeScript are strong-typed, so we already have the "O" on language level, what we actually need is building SQLs in a DSL-like way to make them more coherent and maintainable. |
@janpio could anyone in dev tema pay attention to this, it is a very basic sql query feature |
+1 to "fix" this... |
2+ years later, and this problem is still not resolved, these extra queries might be needed in some cases. I really started re-thinking the usage of these ORMs. specially those who support NoSQL DBs. because they implemented an extra layer of validation to maintain data validity and integrity. |
SELECT
after create
So prisma 5.1.0 finally does not use https://github.com/prisma/prisma/releases/tag/5.1.0 I guess there should be an option to skip this unecessary returning as well |
Also - the use of |
+1 |
Same than many above, we use MySQL so the I hear that we can use raw SQL to do that, but the whole point we're using Prisma is to avoid writing plain SQL and don't have to update all our queries when doing DB changes. I guess that we'll have to migrate to a query builder instead, unless there are any plans from the Prisma team to address this? Given that this issue has been opened since 2020, I'm not sure it is quite a high priority yet on the roadmap 🤔 |
I still can't believe this bug was not fixed. And yes, it is a bug IMO. When you create something, you expect it to be created and that's it. If you want to return fields then you should use |
SELECT
after create
SELECT
after create()
Problem
Every time you do operation with prisma-client it will make unnecessary select and return value
Query:
Logs:
Suggested solution
Add option to skip select after insert or update (in case of operation fail error is thrown by default)
Logs:
Alternative solution (breaking change)
Do not return anything after insert or update if select was not explicitly set.
The text was updated successfully, but these errors were encountered: