如何在 SQLAlchemy 中执行自定义连接

Posted

技术标签:

【中文标题】如何在 SQLAlchemy 中执行自定义连接【英文标题】:how to perform custom join in SQLAlchemy 【发布时间】:2018-10-17 18:56:54 【问题描述】:

我正在使用的数据库没有在表之间创建关系,并且更改架构不是我的选择。

我试图在 orm 中描述如何在不描述 Foregin 键的情况下连接两个表。为了让事情变得更糟,我需要在我的 SQL 中自定义 ON 子句

这是我的 ORM(或多或少):

class Table1(Base):
   __tablename__ = "table1"
   id1 = Column(String)
   id2 = Column(String)

class Table2(Base):
   __tablename__ = "table2"
   id1 = Column(String)
   id2 = Column(String)

目标

我要创建的是relationship,它可以像这样连接表:

.....
FROM Table1
JOIN Table2 ON (Table1.id1 = Table2.id1 OR Table1.id2 = Table2.id2)

我的尝试

我尝试添加以下Table1,但文档没有用我能理解的术语解释这是怎么回事:

table2 = relationship("Table2", 
                      primaryjoin=or_(foreign(id1) == remote(Table2.id1),
                                      foreign(id2) == remote(Table2.id2)))

但是在测试时我得到了错误的 SQL 查询(我希望在 SQL 中看到我上面描述的连接):

str(query(Table1,Table2))

选择“table1”.id1、“table1”.id2、“table2”.id1、“table2”.id2 FROM "table1","table2"

注意

我并不真正了解 remoteforegin 做了什么,但我试图从文档中推断它们属于哪里,否则我会在导入时出错:

ArgumentError:在关系 Table1.other_table 上找不到任何与主连接条件'my full primaryjoin code'相关的外键列。确保引用列与 ForeignKey 或 ForeignKeyConstraint 相关联,或者在连接条件中使用 foreign() 注释进行注释。

我认为我不能使用 ForeignKey 或 ForeignKeyContraint,因为我的所有列都不受其他表的值的限制。

【问题讨论】:

有些相关:***.com/questions/37806625/… 【参考方案1】:

表达式

str(query(Table1,Table2))

如您所见,在 2 个表之间产生交叉连接。这是预期的行为。如果您想使用内部连接等,您必须明确说明:

str(query(Table1, Table2).join(Table1.table2))

这个joins along the relationship attributetable2。该属性指示此连接应如何发生。


foreign()remote() 的文档对我自己的口味也有点分散,但在 "Adjacency List Relationships" 和 "Non-relational Comparisons / Materialized Path" 中建立了当外部和远程注释位于表达式的不同侧时(在ON 子句),该关系被认为是多对一的。当它们在同一侧或远程被省略时,它被认为是一对多的。所以你们的关系被认为是多对一的。

它们只是foreign_keysremote_side 参数的替代品。

【讨论】:

如果我错了,请纠正我,relationship 不会为我创建 Query 中的连接,它只是描述了如何在我明确表示我想要的情况下连接表? 那个,并且该属性作为相关对象的集合(一对多,多对多)/对实例(地图)上相关对象(多对一)的引用关系模型到对象模型)。 :) 谢谢先生,您今天为我节省了数小时的研究时间。

以上是关于如何在 SQLAlchemy 中执行自定义连接的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Flask-SQLAlchemy 中执行多个“order_by”?

SQLAlchemy 中的星型模式

如何在 Elixir 或 SQLAlchemy 中为与其自身的多对一关系创建可自定义的“排序依据”?

SQLalchemy 在设置角色时不提交更改

Sqlalchemy 连接超时

如何在 SQLAlchemy 中加载嵌套关系?