Prisma一对一关联插入数据时pk字段非空约束报错排查
问题相关Schema片段
model ShopifyOfflineStoreSession { pk String @id(map: "PK_d371917bab72a48d6cce7880fc5") @default(dbgenerated("uuid_generate_v4()")) @db.Uuid id String @unique(map: "UQ_91ede9e23efbd7ee27b37bdd9ba") @db.VarChar store Store? @relation(fields: [pk], references: [shopifyOfflineSessionPk], onDelete: Cascade, onUpdate: Cascade, map: "FK_901a837fbbf20119aded3682f90") @@map("shopify_store_session") } model Store { id Int @id(map: "PK_f3172007d4de5ae8e7692759d79") @default(autoincrement()) shopifyOfflineSessionPk String? @unique(map: "UQ_901a837fbbf20119aded3682f90") @db.Uuid shopifyOfflineSession ShopifyOfflineStoreSession? @@map("store") }
执行失败的查询代码
await this.prisma.shopifyOfflineStoreSession.create({ data: { ...session, store: { connect: { id: store.id } }, }, });
报错信息
2022-06-10 16:41:02.035 UTC [15541] ERROR: null value in column "pk" violates not-null constraint 2022-06-10 16:41:02.035 UTC [15541] DETAIL: Failing row contains (null, offline_subbooks2.myshopify.com, 2022-06-10 16:41:02.033, 2022-06-10 16:41:02.033, null, subbooks2.myshopify.com, 005148992241858, f, null, null, null). 2022-06-10 16:41:02.035 UTC [15541] STATEMENT: INSERT INTO "public"."shopify_store_session" ("pk","id","createdAt","updatedAt","shop","state","isOnline") VALUES ($1,$2,$3,$4,$5,$6,$7) RETURNING "public"."shopify_store_session"."pk" Issue saving Shopify offline token. Err: PrismaClientKnownRequestError: Invalid `this.prisma.shopifyOfflineStoreSession.create()` invocation in /usr/src/api/src/store/store.service.ts:576:52 573 data: session, 574 }); 575 } else { → 576 await this.prisma.shopifyOfflineStoreSession.create( Null constraint violation on the fields: (`pk`) at cb (/usr/src/api/node_modules/@prisma/client/runtime/index.js:38683:17) { code: 'P2011', clientVersion: '3.6.0', meta: { constraint: [ 'pk' ] } } query: DELETE FROM "store" WHERE "id" IN ($1) -- PARAMETERS: [18]
错误原因
核心问题是Prisma一对一关系配置完全写反:
- 现有配置在
ShopifyOfflineStoreSession模型的store关系上,指定外键字段是当前模型的主键pk,关联Store模型的shopifyOfflineSessionPk字段。 - 这个配置的实际含义是:
ShopifyOfflineStoreSession表的pk字段是外键,值必须从关联的Store记录的shopifyOfflineSessionPk字段获取。 - 执行
connect关联已有Store记录时,Prisma会读取该Store的shopifyOfflineSessionPk值作为新Session的pk值,不会触发数据库配置的uuid_generate_v4()默认值生成逻辑。而此时待关联的Store记录的shopifyOfflineSessionPk本身就是空值(还未绑定Session),最终插入Session记录时pk字段为null,触发非空约束报错。
修复方案
- 修正关系配置,将外键定义挪到持有外键字段的
Store模型侧,不要占用ShopifyOfflineStoreSession的主键字段当外键:
model ShopifyOfflineStoreSession { pk String @id(map: "PK_d371917bab72a48d6cce7880fc5") @default(dbgenerated("uuid_generate_v4()")) @db.Uuid id String @unique(map: "UQ_91ede9e23efbd7ee27b37bdd9ba") @db.VarChar store Store? @@map("shopify_store_session") } model Store { id Int @id(map: "PK_f3172007d4de5ae8e7692759d79") @default(autoincrement()) shopifyOfflineSessionPk String? @unique(map: "UQ_901a837fbbf20119aded3682f90") @db.Uuid // 外键在当前模型,关系配置写在这里 shopifyOfflineSession ShopifyOfflineStoreSession? @relation( fields: [shopifyOfflineSessionPk], references: [pk], onDelete: Cascade, onUpdate: Cascade, map: "FK_901a837fbbf20119aded3682f90" ) @@map("store") }
- 修正Schema后执行
prisma generate更新客户端,原有创建代码无需额外修改即可正常运行:Prisma会先生成带默认UUID主键的Session记录,再自动更新关联Store的shopifyOfflineSessionPk字段为新Session的主键值,不会再出现pk为null的问题。
内容的提问来源于stack exchange,提问作者Gezim
相关产品推荐
相关产品推荐

