我在 peewee 有以下模型:
db.py
class Item(BaseModel):
item_id = IntegerField()
item_name = CharField()
class Sales(BaseModel):
sales_id = IntegerField()
class SalesItem(BaseModel):
sales_item_id = Integer_Field()
sales = ForeignKeyField(Sales, backref='items')
item = ForeignKeyField(Item)
视图.py
templates = Jinja2Templates(directory="templates")
def html_get(request, sales_id):
sales = Sales.get(Sales.sales_id==sales_id)
return templates.templateResponse('view_sales.html',{'sales':sales})
view_sales.html
Sales: {{ sales.sales_id }}
Items:
{% for it in sales.items %}
<div>{{ it.item.item_name }}</div>
{% endfor %}
问题是查询
sales = Sales.get(Sales.sales_id==sales_id)
生成 O(n+1) 查询来获取每个项目的名称。我尝试创建连接 sales = Sales.select(Sales,SalesItem,Item).join(SalesItem).join(Item).where(Sales.sales_id==sales_id)
但它也会生成 O(n+1) 查询。
我研究过使用预取,但无法让它工作。知道如何将查询减少到 O(k),其中 k=表的数量吗?
通过这些更新,html_get 函数将通过加入 Sales 和 Item 模型并使用 Prefetch 获取相关数据来仅执行一次查询。这将减少查询数量并提高性能。
def html_get(请求, sales_id): sales_query = Sales.select().where(Sales.sales_id == sales_id) sales_with_items = 预取(sales_query, SalesItem.select().join(Item))
return templates.templateResponse('view_sales.html', {'sales': sales_with_items})