gpt4 book ai didi

python-3.x - SqlAlchemy - 多对多外连接,带有连接条件

转载 作者:行者123 更新时间:2023-12-03 22:48:19 25 4
gpt4 key购买 nike

这是我的代码:

Table('contacts', self.metadata,
Column('id', PGUuid, primary_key=True),
Column('first_name', String(150), nullable=False),
Column('middle_name', String(150), nullable=True),
Column('last_name', String(150), nullable=False, index=True),
Column('friendly_name', String(150), nullable=True),
Column('alias', String(450), nullable=False, index=True),
Column('prefix', String(5), nullable=True),
Column('suffix', String(5), nullable=True),
Column('ssn', String(12), nullable=True),
Column('email', String(150), nullable=True),
Column('date_of_birth', Date, nullable=True),
Column('contact_type', String(16), nullable=False))
self._contacts_addresses_table = Table('contacts_addresses', self.metadata,
Column('contact_id', PGUuid, ForeignKey('contacts.id'),
primary_key=True, index=True),
Column('address_id', PGUuid, ForeignKey('addresses.id'),
primary_key=True, index=True))
self._contacts_phones_table = Table('contacts_phones', self.metadata,
Column('contact_id', PGUuid, ForeignKey('contacts.id'),
primary_key=True, index=True),
Column('phone_id', PGUuid, ForeignKey('phones.id'),
primary_key=True, index=True))
self._contacts_notes_table = Table('contacts_notes', self.metadata,
Column('contact_id', PGUuid, ForeignKey('contacts.id'),
primary_key=True, index=True),
Column('note_id', PGUuid, ForeignKey('notes.id'),
primary_key=True, index=True))

mapper(Contact, self._table, column_prefix='_', extension=ContextExtension(),
properties={
'addresses': relationship(Address, lazy='noload', secondary=self._contacts_addresses_table),
'notes': relationship(Note, lazy='noload', secondary=self._contacts_notes_table),
'phones': relationship(Phone, lazy='noload', secondary=self._contacts_phones_table),
'contact_logs': relationship(ContactLog, lazy='noload')})

query(Contact).filter(Contact._id == contact_id) \
.filter(Contact._is_deleted == False) \
.outerjoin((Contact.addresses, Address)) \
.options(contains_eager(Contact.addresses))

这是我的问题:在上面的查询中,我需要在外连接上添加一个额外的条件。
如果我使用过滤器( Address.is_deleted == False ),它将被添加到 WHERE 上而不是在 JOIN ON条款。

一些注意事项:我没有使用延迟加载,也不想使用它。我不想在关系定义上强制执行条件。实现此目的的一种方法是通过子查询。
但是在这种情况下我也有一些问题,如果我多次别名(或者如果 SqlAlchemy 这样做)相同的表并且这些别名表在外连接中使用,SqlAlchemy 创建一个错误的查询,我最终会得到一个交叉连接,例如: SELECT ... FROM contacts, phones, addresses ...

最佳答案

如果你需要一个不同于 relationship() 的 JOIN 条件定义,那么您不能使用该关系进行连接。你必须明确地拼写出来:

query(Contact).filter(Contact._id == contact_id) \
.filter(Contact._is_deleted == False) \
.outerjoin(self._contacts_addresses_table) \
.outerjoin(Address, and_(Address.id == self._contacts_address_table.c.address_id, Address.deleted == False)) \
.options(contains_eager(Contact.addresses))

子查询方法也是可能的。我不确定您在那里寻找什么查询,但您描述的 FROM 子句问题表明您没有正确使用别名子查询对象。

如果是我,我只需添加一个名为“non_deleted_addresses”的附加关系 viewonly=True和新标准,并将其用于连接。

关于python-3.x - SqlAlchemy - 多对多外连接,带有连接条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22909531/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com