【问题标题】:Way to filter using a backref "length" with SQLAlchemy使用带有 SQLAlchemy 的反向引用“长度”进行过滤的方法
【发布时间】:2013-08-13 22:26:10
【问题描述】:

我在两种类型的对象 Message 和 URL 之间有一对多的关系。在类 URL 中定义了一个关系,其中一个名为“link”的反向引用指向 Message。有没有办法在查询消息时进行过滤,以查找例如拥有少于 n 个 URL 的消息?

我试过了:

session.query(Message).filter(len(Message.link) < n).all()

还有

from sqlalchemy import func
session.query(Message).filter(func.count(Message.link) < n).all()

他们每个人都给我发回一个错误。第一个:

InstrumentedAttribute has no len()

第二个:

DatabaseError: (DatabaseError) ORA-00934: group function is not allowed here

感谢 Audrius Kažukauskas,经过一番摆弄,我设法完成了以下查询:

session.query(Message.message_id)\
       .join(URL)
       .group_by(Message.message_id)
       .having(func.count(URL.url_id) <= n)

效果很好(发回 KeyedTuple 而不是 Message 集合,但我可以接受)。

【问题讨论】:

    标签: python python-2.7 orm sqlalchemy


    【解决方案1】:

    为此,您需要将MessageURL 连接起来,按Message 中的所有字段分组并在HAVING 子句中进行过滤:

    q = session.query(Message).\                                                     
        join(URL).\                                                                  
        group_by(Message).\                                                          
        having(func.count(URL.id) < n)
    

    filter()(在 SQL 中转换为 WHERE)应用于之前分组和聚合函数,而having() 过滤行之后分组完成。

    【讨论】:

    • 我在使用它时收到“DatabaseError: (DatabaseError) ORA-00932: compatible datatypes: expected - got NCLOB”错误(我在 Message 中的一列有这种类型。
    • 当我输入 group_by(Message.message_id) 时,我得到一个不错的“DatabaseError: (DatabaseError) ORA-00979: not a GROUP BY expression”异常.....
    • 嗯,这很奇怪......我没有使用 Oracle 的经验,但我的查询适用于 PostgreSQL 和 SQLite(即使在修改 group_by() 之后像你一样)。尽管我必须指出,我为测试查询而创建的模型非常简单。
    • 问题出在一个该死的 clob 上,如果我像那个查询(消息)一样将整个对象放在查询中,cx_Oracle 会因为比较而吓坏了,但是如果我放一个特定的列(查询( Message.message_id)) 具有“nice”类型,例如一个整数,比较器对此感到满意并发回结果。
    猜你喜欢
    • 2016-11-03
    • 1970-01-01
    • 2017-07-17
    • 1970-01-01
    • 2012-10-30
    • 2020-10-05
    • 1970-01-01
    • 1970-01-01
    • 2014-11-22
    相关资源
    最近更新 更多