首页 > 解决方案 > 如何在 SQLAlchemy 中执行自定义连接

问题描述

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

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

这是我的 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”、“table2”中选择“table1”.id1、“table1”.id2、“table2”.id1、“table2”.id2

笔记

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

ArgumentError:在关系 Table1.other_table 上找不到主连接条件“我的完整主连接代码”的任何相关外键列。确保引用列与 ForeignKey 或 ForeignKeyConstraint 相关联,或者在连接条件中使用 foreign() 注释进行注释。

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

标签: pythonsqlalchemy

解决方案


表达方式

str(query(Table1,Table2))

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

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

沿着关系属性连接 table2。该属性指示此连接应如何发生。


foreign()和上的文档remote()也有点分散,我自己的口味,但是在“邻接列表关系”“非关系比较/物化路径”中确定,当外部和远程注释位于表达式的不同侧时(在ON 子句),该关系被认为是多对一的。当它们在同一侧或远程被省略时,它被认为是一对多的。因此,您的关系被认为是多对一的。

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


推荐阅读