[英]Seeding with prisma nested create with one-to-one relation
目前正在開展一個項目,以使用 nestjs 了解更多關於 prisma 的信息。 但不能讓架構工作。 種子不會 go 通過,因為平面依賴於所有者字段,只能用創建的用戶填充。
我想創建一個簡單的數據庫設置,其中用戶可以是公寓的所有者,但必須擁有公寓。
一個公寓需要有一個所有者,並且可以有多個租戶。
非常感謝這里的幫助,否則它只是另一個永遠不會克服概念的項目。
架構:
model User {
userId String @id @default(uuid())
firstName String?
lastName String?
nickname String
email String @unique
password String
phoneNumber String?
ownerOf Flat? @relation("owner")
ownerOfId String? @unique
flatId String
flat Flat @relation(fields: [flatId], references: [flatId])
paidFor Expense[] @relation("paidBy")
otherExpenses Expense[]
updatedAt DateTime? @updatedAt
createdAt DateTime? @default(now())
@@map("users")
}
model Flat {
flatId String @id @default(uuid())
name String
owner User? @relation("owner", fields: [ownerId], references: [userId])
ownerId String? @unique
flatmates User[]
expenses Expense[]
updatedAt DateTime? @updatedAt
createdAt DateTime? @default(now())
@@map("flats")
}
model Expense {
expenseId String @id @default(uuid())
flatId String
flat Flat @relation(fields: [flatId], references: [flatId])
paidBy User @relation("paidBy", fields: [paidById], references: [userId])
paidById String
expenseFor User[]
amount Float
updatedAt DateTime? @updatedAt
createdAt DateTime? @default(now())
@@map("expenses")
}
const users = await prisma.user.create({
data: {
firstName: 'Flo',
lastName: 'Test',
nickname: 'flo',
email: 'test@test.de',
password: hash,
flat: {
create: {
name: 'Test Flat',
owner: {
connect: {
users,
},
},
},
},
},
});
您需要先創建user
,然后在后續操作中connect
flat
。 我會將其包裝在交互式事務中。
我會開始考慮關系。
附加要求是:
owner
仍然是可選的您可以 model 這些關系在您的schema.prisma
(簡化)中像這樣:
model User {
userId String @id @default(uuid())
nickname String
flatId String
flat Flat @relation(fields: [flatId], references: [flatId], name: "tenantRelation")
ownedFlat Flat? @relation(name: "ownerRelation")
@@map("users")
}
model Flat {
flatId String @id @default(uuid())
name String
ownerId String? @unique
owner User? @relation(fields: [ownerId], references: [userId], name: "ownerRelation")
tenants User[] @relation(name: "tenantRelation")
@@map("flats")
}
無需引入多余的User.ownerOfId
。
該模式不保證每個公寓都有一個所有者,因為ownerId
是可選的。
如果你接受這個缺陷,你可以像這樣創建用戶和平面:
await prisma.user.create({
data: { nickname: "flo", flat: { create: { name: "Test flat" } } },
});
然后在第二步中將公寓的所有者設置為用戶...
owner
應該是強制性的如果您不接受這個缺陷,並且將ownerId
非可選,那么播種確實會變得更加困難,因為您有循環依賴。
在架構中,您只需刪除兩個問號:
model Flat {
...
ownerId String @unique
owner User @relation(fields: [ownerId], references: [userId], name: "ownerRelation")
...
然后,您必須:
DEFERRABLE INITIALLY DEFERRED
或DEFERRABLE INITIALLY IMMEDIATE
。 目前,prisma 無法做到這一點(參見: https://github.com/prisma/prisma/issues/8807 )。import { v4 as uuidv4 } from "uuid";
// ...
const userId = uuidv4();
const flatId = uuidv4();
await prisma.$transaction(async ($tx) => {
await $tx.$executeRaw`set constraints all deferred;`;
await $tx.$executeRaw`INSERT INTO users ("userId", "nickname", "flatId") VALUES (${userId}, 'flo', ${flatId});`;
await $tx.$executeRaw`INSERT INTO flats ("flatId", "name", "ownerId") VALUES (${flatId}, 'Test flat', ${userId});`;
});
目前需要在您的schema.prisma
中使用previewFeatures = ["interactiveTransactions"]
。
但在走這條路之前,我建議仔細檢查您的應用程序將如何真正使用數據庫。 用戶和平面是否總是在同一步驟中創建?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.