Prisma is not joining tables when making a query with referentialIntegrity feature
See original GitHub issueBug description
Our database does not have foreign keys. To maintain relations, we’re using referentialIntegrity
:
generator client {
provider = "prisma-client-js"
previewFeatures = ["referentialIntegrity"]
}
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
referentialIntegrity = "prisma"
}
When calling prisma.foo.update
, where foo
has a relation with bridge table foo_bar
. The problem is that prisma is not performing a join between foo
and bar
while trying to select data from both tables in one SELECT
statement.
When I invoke this script:
const updated = await prisma.merchant.update({
where: { id: merchant.id },
data: { currency: 'USD' },
});
This are the queries logged by prisma:
BEGIN
SELECT
`my-local`.`merchant`.`id`
FROM
`my-local`.`merchant`
WHERE
`my-local`.`merchant`.`id` = ?
SELECT
`my-local`.`server`.`id`,
`my-local`.`server`.`merchant_id`
FROM
`my-local`.`server`
WHERE
(1=1 AND `my-local`.`server`.`merchant_id` IN (?))
SELECT
`my-local`.`refund_event`.`id`,
`my-local`.`refund_event`.`merchant_id`
FROM
`my-local`.`refund_event`
WHERE
(1=1 AND `my-local`.`refund_event`.`merchant_id` IN (?))
SELECT
`my-local`.`foo`.`id`,
`my-local`.`foo`.`merchant_id`
FROM
`my-local`.`foo`
WHERE
(1=1 AND `my-local`.`foo`.`merchant_id` IN (?))
SELECT
`my-local`.`foo`.`id`,
`my-local`.`foo_bar`.`foo_id`,
`my-local`.`foo_bar`.`bar_id`
FROM
`my-local`.`foo_bar`
WHERE
1=0
ROLLBACK
The error that follows is:
Invalid `prisma.merchant.update()` invocation in
api/src/merchant/resolvers/mutation/toggleAcceptingOrders.ts:53:45 50 });
51 */ 52 → 53 const updated = await prisma.merchant.update( The column `my-local.foo.id`
does not exist in the current database.
Specifically, the error is caused by
SELECT
`my-local`.`foo`.`id`,
`my-local`.`foo_bar`.`foo_id`,
`my-local`.`foo_bar`.`bar_id`
FROM
`my-local`.`foo_bar`
A join is needed between foo and foo_bar.
The only thing I’ve found to work is to disable referentialIntegrity
.
How to reproduce
With no foreign keys in your database, enable referentialIntegrity
in your prisma schema:
generator client {
provider = "prisma-client-js"
previewFeatures = ["referentialIntegrity"]
}
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
referentialIntegrity = "prisma"
}
Use a table (merchant
) such that it has a one-to-many relationship with table foo
and table foo
has a relation to a bridge table foo_bar
.
Then, call a prisma.merchant.update()
and watch the Invalid
prisma.merchant.update() invocation
error occur following the same pattern as described above.
Expected behavior
No response
Prisma schema (roughly)
model Merchant {
id Int @id @default(autoincrement()) @db.UnsignedInt
bars Bar[]
foos Foo[]
@@map("merchant")
}
model Foo {
id Int @id @default(autoincrement()) @db.UnsignedInt
merchant Merchant @relation(fields: [merchantId], references: [id])
merchantId Int @map("merchant_id") @db.UnsignedInt
fooBars FooBar[]
@@map("foo")
}
model FooBar {
bar Bar @relation(fields: [barId], references: [id])
barId Int @map("barId") @db.UnsignedInt
foo Foo @relation(fields: [fooId], references: [id])
fooId Int @map("foo_id") @db.UnsignedInt
@@id([fooId, barId])
@@index([barId], map: "bar_id")
@@map("foo_bar")
}
model Bar {
id Int @id @default(autoincrement()) @db.UnsignedInt
merchant Merchant @relation(fields: [merchantId], references: [id])
merchantId Int @map("merchant_id") @db.UnsignedInt
fooBars FooBar[]
@@map("bar")
}
Environment & setup
- OS: Mac OS 12.2.1
- Database: MySQL 8.0.28
- Node.js version: 16.14.2
Prisma Version
3.9.1
Issue Analytics
- State:
- Created a year ago
- Reactions:1
- Comments:8 (5 by maintainers)
Top GitHub Comments
Thanks for the quick response! Yes, let’s close this as a duplicate.
I expanded that other issue’s title, and posted a comment: https://github.com/prisma/prisma/issues/10758#issuecomment-1098430578
If you agree with all this, we can close this issue here as a duplicate I think. Thanks for the great report and iteration on it.