簡體   English   中英

在 peewee (Flask) 中的查詢中包含 OneToMany 關系

[英]Include OneToMany relationship in query in peewee (Flask)

我有兩個型號的存儲和抽屜

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)

但我只是檢索了有抽屜的第二個存儲空間,但不包括抽屜陣列。 這甚至可以通過連接實現嗎? 或者我是否需要遍歷每個存儲檢索抽屜並將它們附加到存儲?

這是 ORM 的經典 O(n) 查詢問題。 該文檔詳細介紹了解決該問題的各種方法

對於這種情況,您可能需要prefetch() 它將執行 O(k) 個查詢,而不是 O(n) 個查詢,每個涉及的表一個(在您的情況下為 2 個)。

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

為了序列化它,我們將遍歷prefetch返回的 Storage 對象。 相關的抽屜會一直使用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))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM