SQLAlchemy中使用join实现混合属性

5

我可能还没有完全掌握@hybrid_property的用法。但是我的目标是使基于另一个表中的列进行计算的值易于访问,因此需要进行连接。

所以我有类似于这样的东西(它可以工作,但很笨拙,感觉不对):

class Item():

:

@hybrid_property
def days_ago(self):
    # Can I even write a python version of this ?
    pass

@days_ago.expression
def days_ago(cls):
    return func.datediff(func.NOW(), func.MAX(Event.date_started))

这要求我在需要使用days_ago属性时,由调用者在Action表上添加连接。混合属性是否是简化查询并获取days_ago值的正确方法?
1个回答

9
无论如何,您需要通过连接或惰性加载来加载或访问Action行(请注意,这里不清楚EventAction的区别,我假设您只有Item.actions -> Action)。
非“表达式”版本的days_ago旨在针对仅与当前实例相关的Action对象进行操作。通常,在混合中,这意味着只需迭代Item.actions并针对已加载的Action对象在Python中执行操作即可。但是,在这种情况下,您正在寻找一个简单的聚合,因此可以选择运行查询,但再次,它将局限于self,因此类似于 object_session(self).query(func.datediff(...)).select_from(Action).with_parent(self).scalar()
当对另一个表形成该混合物的表达式版本时,通常要求在其中使用它的查询已经设置了正确的FROM子句,因此它看起来像session.query(Item).join(Item.actions).filter(Item.days_ago == xyz)。这在Join-Dependent Relationship Hybrid中有解释。
如果您可以承担使用相关子查询,则可能更好地将此表达式作为column_property生成。请参见http://docs.sqlalchemy.org/en/latest/orm/mapping_columns.html#using-column-property-for-column-level-options

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接