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

时间:2018-10-17 18:56:54

标签: python sqlalchemy

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

我试图在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   来自“ table1”,“ table2”

注意

我并没有真正理解remoteforegin的作用,但是我试图从文档中推断它们的归属,否则导入错误会出现错误:

  

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

我不认为我可以使用ForeignKey或ForeignKeyContraint,因为我的所有列都不限于其他表的值。

1 个答案:

答案 0 :(得分:1)

表达式

str(query(Table1,Table2))
如您所见,

在两个表之间产生交叉联接。这是预期的行为。如果要使用内部联接等,则必须对此进行明确说明:

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

joins along the relationship attribute table2。该属性指示此连接应如何发生。


foreign()remote()上的文档也散布了一些我自己的喜好,但是在"Adjacency List Relationships""Non-relational Comparisons / Materialized Path"中建立了在使用外部和远程注释的情况下的文档。在表达式的不同侧(在ON子句中),该关系被认为是多对一的。当它们在同一侧或远程时,将被视为一对多。因此,您的关系被认为是多对一的。

它们只是foreign_keysremote_side参数的替代。