如何在SQLAlchemy中连接同一张表格

17

我正在尝试在SQLAlchemy中加入相同的表。这是我尝试过的最小化版本:

#!/usr/bin/env python
import sqlalchemy as sa
from sqlalchemy import create_engine
from sqlalchemy.orm import mapper, sessionmaker, aliased

engine = create_engine('sqlite:///:memory:', echo=True)

metadata = sa.MetaData()
device_table = sa.Table("device", metadata,
    sa.Column("device_id", sa.Integer, primary_key=True),
    sa.Column("name", sa.String(255), nullable=False),
    sa.Column("parent_device_id", sa.Integer, sa.ForeignKey('device.device_id')),
    )

class Device(object):
    device_id = None
    def __init__(self, name, parent_device_id=None):
        self.name = name
        self.parent_device_id = parent_device_id

    def __repr__(self):
        return "<Device(%s, '%s', %s)>" % (self.device_id,
                                           self.name,
                                           self.parent_device_id )

mapper(Device, device_table)

metadata.create_all(engine)

db_session = sessionmaker(bind=engine)()

parent = Device('parent')
db_session.add(parent)
db_session.commit()

child = Device('child', parent.device_id)
db_session.add(child)
db_session.commit()

ParentDevice = aliased(Device, name='parent_device')
q = db_session.query(Device, ParentDevice)\
    .outerjoin(ParentDevice,
               Device.parent_device_id==ParentDevice.device_id)

print list(q)

我遇到了这个错误:

ArgumentError:无法确定“device”和“parent_device”之间的连接;这两个表之间有多个外键约束关系。请显式指定此连接的“onclause”。

但是我已经为连接指定了一个onclause,我应该如何处理?

2个回答

8

对于 query.[outer]join,您需要指定一个连接列表(与 expression.[outer]join 不同)。因此,我需要将连接的两个元素,表格和 onclause 放在一个元组中,如下所示:

q = db_session.query(Device, ParentDevice)\
    .outerjoin(
                  (ParentDevice, Device.parent_device_id==ParentDevice.device_id)
              )

3
您的映射器应指定两个项目之间的连接,这是一个例子:邻接列表关系

我无法使其在上述示例中正常工作,但感谢您指向该文档。它向我介绍了一些我不知道的SQLAlchemy部分,这对我在应用程序的其他部分将会很有用。 - Gary van der Merwe
供日后参考... 此链接 更为最新,并提供了一个使用声明式的示例。 - Russ

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接