pat*_*ckn 5 python django sqlalchemy
我想将Django模型管理器中的以下注释转换为SQLAlchemy ORM查询:
annotations = {
'review_count' : Count("cookbookreview", distinct=True),
'rating' : Avg("cookbookreview__rating")
}
return self.model.objects.annotate(**annotations)
Run Code Online (Sandbox Code Playgroud)
我本质上需要的是在查询中有每个模型对象review_count,并rating连接到它们作为初始查询的一部分。我相信我可以使用column_property,但是我想避免在对象上使用这种类型的“计算属性”,因为当我访问模板中的属性时,我不希望为每个对象完成该属性(昂贵的查找)。
解决这个问题的正确方法是什么?提前致谢。
因此,出于对这个问题的完整性和实用性的考虑,我提出以下解决方案(可能是也可能不是解决此问题的最佳方法)
sq_reviews = db_session.query(CookbookReview.cookbook_id,
func.avg(CookbookReview.rating).label('rating'),\
func.count('*').label('review_count')).\
group_by(CookbookReview.cookbook_id).subquery()
object_list = db_session.query(
Cookbook, sq_reviews.c.rating, sq_reviews.c.review_count).\
outerjoin(sq_reviews, Cookbook.id==sq_reviews.c.cookbook_id).\
order_by(Cookbook.name).limit(20)
Run Code Online (Sandbox Code Playgroud)
这里的关键是SQLAlchemy子查询的概念。如果您将我最初的Django查询中的每个注释都视为子查询,则该概念更易于理解。还值得注意的是,此查询的速度非常快-比Django(更简洁/更神奇)的查询速度快了多个数量级。希望这可以帮助其他人对此特定的Django / SQLAlchemy查询模拟感到好奇。
还要记住,您需要自己执行ORM对象的实际注释。在将对象列表发送到模板之前调用一个简单的函数就足够了:
def process(query):
for obj, rating, review_count in query:
obj.rating = rating
obj.review_count = review_count
yield obj
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1405 次 |
| 最近记录: |