【问题标题】:Include OneToMany relationship in query in peewee (Flask)在peewee(Flask)的查询中包含OneToMany关系
【发布时间】:2017-05-08 21:35:21
【问题描述】:

我有两种型号 Storage 和 Drawers

class Storage(BaseModel):
    id = PrimaryKeyField()
    name = CharField()
    description = CharField(null=True)

class Drawer(BaseModel):
    id = PrimaryKeyField()
    name = CharField()
    storage = ForeignKeyField(Storage, related_name="drawers")

目前我正在通过选择查询生成 json

storages = Storage.select()

结果我得到了一个 json 数组,如下所示:

[{
   description: null,
   id: 1,
   name: "Storage"
},
{
   description: null,
   id: 2,
   name: "Storage 2"
}]

我知道,peewee 允许使用storage.drawer() 查询所有抽屉。但是我正在努力为每个包含该存储的所有抽屉的存储包含一个 json 数组。我尝试使用连接

storages = Storage.select(Storage, Drawer)
                  .join(Drawer)
                  .where(Drawer.storage == Storage.id)
                  .group_by(Storage.id)

但我只是检索了第二个有抽屉的存储,但不包括抽屉数组。这甚至可以通过连接实现吗?还是我需要遍历每个存储检索抽屉并将它们附加到存储?

【问题讨论】:

    标签: python json flask peewee


    【解决方案1】:

    这是 ORM 的经典 O(n) 查询问题。文档goes into some detail on various ways to approach the problem

    对于这种情况,您可能需要prefetch()。它不会执行 O(n) 次查询,而是执行 O(k) 次查询,每个涉及的表一个(在您的情况下为 2 个)。

    storages = Storage.select().order_by(Storage.name)
    drawers = Drawer.select().order_by(Drawer.name)
    query = prefetch(storages, drawers)
    

    为了序列化它,我们将遍历prefetch 返回的存储对象。相关的抽屉将使用 Drawer.storage 外键的 related_name + '_prefetch' (drawers_prefetch) 预先填充:

    accum = []
    for storage in query:
        data = {'name': storage.name, 'description': storage.description}
        data['drawers'] = [{'name': drawer.name}
                           for drawer in storage.drawers_prefetch]
        accum.append(data)
    

    为了使这更容易,您可以使用playhouse.shortcuts.model_to_dict 助手:

    accum = []
    for storage in query:
        accum.append(model_to_dict(storage, backrefs=True, recurse=True))
    

    【讨论】:

    • 谢谢!像魅力一样工作,一定错过了文档的这个特定部分。搜索时使用了错误的流行语。
    猜你喜欢
    • 1970-01-01
    • 2014-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多