从 Prisma 中的多对多表中获取元信息
Posted
技术标签:
【中文标题】从 Prisma 中的多对多表中获取元信息【英文标题】:Getting meta information from many-to-many table in Prisma 【发布时间】:2021-06-20 14:23:17 【问题描述】:我有这个表结构
注意item_level
键
我需要完成的是拥有相同的物品,连接到许多玩家,但每个玩家都可以独立升级物品。
这是我能想到的最简单的结构,用 sql 术语来说,连接表、选择字段并显示这些连接很容易。
我的问题是,我正在使用 Apollo graphql 和 Prisma ORM (v ^2.18.0),即使我可以得到每个玩家的物品,但我也可以-versa,我不知道如何包含那个额外的字段。
prisma.schema
model Player
id Int @id @default(id())
items ItemToPlayer[]
model Item
id Int @id @default(id())
players ItemToPlayer[]
model ItemToPlayer
player Player @relation(fields: [playerId], references: [id])
playerId Int
item Item @relation(fields: [itemId], references: [id])
itemId Int
itemLevel Int @default(0)
@@id([playerId, itemId])
类型定义
const typeDefs = gql`
type Player
id: ID!
items: [Item]
type Item
id: ID!
players: [Player]
type ItemToPlayer
playerId: Int!
itemId: Int!
itemLevel: Int!
`;
解析器
const resolvers =
Player:
items: (parent, args, context, info) =>
return context.db.item.findMany(
where:
players:
some:
playerId: parent.id
,
include:
players: true
);
,
,
Item:
players: (parent, args, context, info) =>
return context.db.player.findMany(
where:
items:
some:
itemId: parent.id
,
include:
items: true
);
,
,
Query: /* ... */ ,
Mutation: /* ... */ ,
;
这是我在查询玩家包括他们的物品时想要得到的结果
"data":
"players": [
"id": 1
"items": [
"id": 1,
"itemLevel": 2 // <--- This is missing
,
"id": 2,
"itemLevel": 3
,
]
,
"id": 2
"items": [
"id": 1,
"itemLevel": 0 // same item (id: 1) has different level per player
]
,
]
在documentation 中,它将此描述为显式多对多关系,并提到
请注意,适用与 1-n 关系相同的规则(因为 Post↔ CategoriesOnPosts 和 Category ↔ CategoriesOnPosts 实际上都是 1-n-relations),这意味着关系的一侧需要是 使用@relation 属性进行注释。
但它没有提供示例。
进一步研究1-n-relations
和@relation
,我发现的唯一示例是外键。
在 Internet 上搜索时,我发现其他人就不同的框架和 ORM 提出相同的问题,但没有找到 Prisma。 (除非我错过了)
【问题讨论】:
【参考方案1】:我建议将您的 typedef 更改为:
const typeDefs = gql`
type Player
id: ID!
items: [ItemToPlayer]
type Item
id: ID!
players: [ItemToPlayer]
type ItemToPlayer
playerId: Int!
itemId: Int!
itemLevel: Int!
player: Player!
item: Item!
`;
然后Item
中的players
解析器将如下所示:
prisma.player.findMany(
where:
items:
some:
itemId: parent.id,
,
,
,
include:
items: include: item: true ,
,
)
【讨论】:
将 typeDefs 更改为ItemToPlayer
而不是 Item
有帮助,因为我可以在 db 中查询 itemToPlayer,然后在结果中查询 Item。嵌套的include
给了我一个错误。我设法在没有嵌套包含的情况下做到了。不过,我确实必须修改查询本身。【参考方案2】:
正如@Ryan 在他的回答中建议的那样,我设法通过将Item
更改为ItemToPlayer
并更改我的查询和解析器来获取元数据。
新的Item
解析器
Item:
players: (parent, args, context, info) =>
return context.db.itemToPlayer.findMany(
where:
itemId: parent.id
,
include:
item: true
);
,
,
我现在正在查询ItemsToPlayers
表并取回ItemToPlayer
类型,然后我可以从中查询Item
CORRECT
query
players
id
items
id
itemLevel
item
id
WRONG
query
players
id
items
id
itemLevel <--- This is wrong as itemLevel
does not exist in Item
结果
"data":
"players": [
"id": 1
"items": [
"itemLevel": 2
"item":
"id": 1,
,
"itemLevel": 0
"item":
"id": 1,
,
]
,
]
【讨论】:
以上是关于从 Prisma 中的多对多表中获取元信息的主要内容,如果未能解决你的问题,请参考以下文章