自行联接表以查找具有相同关系的用户

时间:2019-01-14 13:45:54

标签: python sqlalchemy pyramid

编辑:对我来说是最后一次机会,简短的问题

我想使用sqlalchemy进行此查询:

SELECT          first.* , 
                second.* , 
                third.* , 
                fourth.* , 
                mytable.* , 
                mytablesamerelationexist.* 
FROM            third 
LEFT OUTER JOIN mytable 
ON              third.id = mytable.id_third 
LEFT OUTER JOIN first 
ON              first.id = mytable.id_first 
LEFT OUTER JOIN second 
ON              second.id = mytable.id_second 
LEFT OUTER JOIN fourth 
ON              fourth.id = mytable.id_fourth 
LEFT OUTER JOIN mytable AS mytablesamerelationexist 
ON              mytable.id_second = mytablesamerelationexist.id_second 
AND             ( 
                                mytable.id_first = mytablesamerelationexist.id_first 
                OR              ( 
                                                mytable.id_first IS NULL 
                                AND             mytablesamerelationexist.id_first IS NULL ) 
                AND             mytable.id_third = {MYUSERPARAM} )

我想使用contains_eager访问类似以下内容的对象:

third.Mytable.MyTableSameRelationExist

查询的其余部分已经起作用,我只需要进行自我连接即可。

mytable.id_first可以为NULL

我的模型定义最少为model definition

常见问题

联接表自身的最佳方法是什么。我的表包含4个外键,我需要使用其中的两个来找到相同的关系。这些外键之一可以为null。我需要获得关系NULL == NULL。我不想在表中自己定义外键。

我尝试用类似这样的内容定义查询:

tablealias = aliased(MyTable)
...
outerjoin(tablealias , and_(or_(MyTable.id_first == tablealias.first,
                                and_(MyTable.id_first.is_(None),
                                     tablealias.id_first.is_(None))),
                                MyTable.id_second == tablealias.id_second,
                            tablealias.id_third == MYUSERID)).

我想以分层方式访问该关系的结果,例如MyTable.self_child

因此我在查询中添加了

options(contains_eager(MyTable.self_parent, MyTable.self_child))

我已经在我的 MyTable 类中尝试了很多事情,以使关系“ self_child”正常工作而无需在其自身上添加外键。

现在我已经将id_second定义为外键,因为id_first可以为null,我认为这可能是个问题(对吗?):

self_parent = relationship("MyTable",  primaryjoin='foreign(mytable.id_second) == remote(foreign(mytable.id_second))')
self_child = relationship("MyTable", primaryjoin='foreign(mytable.id_second) == remote(mytable.id_second)')

使用此定义,当我初始化数据库时,出现错误:

  

“表格”对象没有属性“ id_second”

如果没有外键来自我,是否需要在我的班级中添加关系?如果没有必要,如何使用contains_eager访问关系定义?如何正确定义它?

编辑: 我通过下面的错误,但是我遇到了很多不同的错误,例如

  

列名不明确

  

它们是同一实体

对于最后的错误,我在Class中定义了我的代码,例如:

self_child = relationship("MyTable", primaryjoin=and_(or_(foreign(id_first) == id_first, and_(foreign(id_first).is_(None), id_first.is_(None))).self_group(), foreign(id_second) == id_second).self_group(), remote_side=[id_second, id_first], lazy='joined')

查询:

tablealias = aliased(MyTable)
...
outerjoin(crotalias.self_child)
...
options(contains_eager(FirstLevel.mytable, crotalias.self_child))

如果我使用backref="self_parent"

我收到消息:

  

MyTable.self_child和反向引用MyTable.self_parent都是   相同的方向符号(“ ONETOMANY”)。你是说定   remote_side在多对一方面?

编辑: 我的模型定义最少为model definition

任何提示将不胜感激。

1 个答案:

答案 0 :(得分:0)

很惊讶,我还没有收到关于这个问题的提示。

现在我使用了第二个主意,我在用户会话中添加了id_first和id_second的列表。因此,我可以遍历查询结果以与用户值相匹配。