【问题标题】:Correlating a SQLAlchemy relationship with an awkward join将 SQLAlchemy 关系与尴尬的连接相关联
【发布时间】:2016-11-15 16:13:50
【问题描述】:

我有以下课程:

class A:
    a_id = Column(Integer, primary_key=True)
    a_remote = Column(UnicodeText)

class B:
    b_id = Column(Integer, primary_key=True)
    foreign_to_a = Column(UnicodeText)
    maximum_a = relationship(A, primaryjoin=lambda:
      and_(remote(a_remote) == foreign(foreign_to_a),
           A.a_id = select([func.max(A.a_id)]).where(A.a_remote == B.foreign_to_a))
    )

换句话说,我正在尝试创建一个关系 maximum_a 与给定 B 指向的所有 A 中最大的 a_id。我特别希望这是一个关系,以便我可以使用 @ 预取它987654328@ 以避免我们现在有 O(N) 个查询的情况。

当我尝试预加载 maximum_a 关系时(例如通过 session.query(B).options(joinedload('maximum_a')).all()),我收到以下错误:

sqlalchemy.exc.InvalidRequestError: Select statement 'SELECT max(a_1.a_id) AS max_1
FROM a AS a_1, b
WHERE a_1.a_remote = b.foreign_to_a' returned no FROM clauses due to auto-correlation; specify correlate(<tables>) to control correlation manually.

我尝试阅读有关相关性的 SQLA 文档,但它们都是根据原始 select 而不是 ORM 调用编写的,并且描述不是很清楚,所以我不确定在哪里添加correlate 调用--或者如果有更好的方法来做到这一点。

有什么建议吗?谢谢!

【问题讨论】:

  • 您能否详细说明其相关性?这个问题似乎与继承或多态无关。
  • 对不起,本。我可能误读了这个问题。我建议继承作为获得所需结果的一种手段,但在重新阅读问题后,我认为它不适合你的情况。
  • 嗯——由于连接条件中的 SELECT 错误(可能是 Postgres 特有的问题),该配方对我不起作用?无论如何,它让我意识到我可以尝试通过使用辅助连接将 SELECT 移出连接条件,这最终让我找到了解决方案,非常感谢!

标签: python orm sqlalchemy


【解决方案1】:

经过多次尝试,以下是有效的方法:

class A:
    a_id = Column(Integer, primary_key=True)
    a_remote = Column(UnicodeText)

latest_a = select([
    func.max(A.a_id).label('a_id'), A.a_remote
]).group_by(A.a_remote).alias('latest_a')

class B:
    b_id = Column(Integer, primary_key=True)
    foreign_to_a = Column(UnicodeText)
    maximum_a = relationship(A,
        secondary=latest_a,
        primaryjoin=latest_a.c.a_remote == foreign_to_a,
        secondaryjoin=latest_a.c.a_id == A.a_id,
        uselist=False, viewonly=True)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-11-02
    • 2011-03-20
    • 1970-01-01
    • 1970-01-01
    • 2014-05-26
    • 1970-01-01
    • 1970-01-01
    • 2018-11-24
    相关资源
    最近更新 更多