SqlAlchemy - Many to Many outer join with conditions on join

Mihai H

Here is my code:

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))

Here is my issue: In the above query I need to add an extra condition on the outer join. If I use filter(Address.is_deleted == False) it will be added on the WHERE and not on the JOIN ON clause.

Some notes: I am not using lazy loading and I do not want to use it. I do not want to enforce the condition on relation definition. One way to achieve this is through subqueries. But I have some issues in that case also, if I alias (or if SqlAlchemy does it) same tables multiple times and those aliased tables are used in an outer join, SqlAlchemy creates a wrong query, I end up with a cross join such as: SELECT ... FROM contacts, phones, addresses ...

zzzeek

if you need a JOIN condition different from what the relationship() defines, then you can't use that relationship to do the join. You have to spell it out explcitly:

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))

the subquery method is also possible. I'm not sure what query you're looking for there but the FROM clause issue you describe indicates you're not using the aliased subquery object appropriately.

if it were me, I'd just add an additional relationship called "non_deleted_addresses" with viewonly=True and the new criteria, and use that for the join.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

SqlAlchemy - Many to Many outer join with conditions on join

From Dev

SQLAlchemy many-to-many LEFT OUTER JOIN with sorted list of entities

From Dev

JPQL left outer join on many to many relationship

From Dev

SQL - One to Many join with left outer join

From Dev

Sqlalchemy one to many relationship join?

From Dev

Could not determine join condition with many-to-many join Sqlalchemy

From Dev

EF LEFT OUTER JOIN instead of INNER JOIN in one to many relationships

From Dev

SQL Server : join tables with many conditions

From Dev

Linq outer join with conditions

From Dev

Many to Many relation with join table

From Dev

Many to many join Php/mysql

From Dev

How to join many to many in createQuery()

From Dev

Doctrine many to many left join

From Dev

Order_by in sqlalchemy with outer join

From Dev

Order_by in sqlalchemy with outer join

From Dev

Left Outer Join with Complex conditions

From Dev

left outer join in R with conditions

From Dev

Left Outer Join with Complex conditions

From Dev

SQLAlchemy join a "one to many table" and then filter on the joined table with a set of values

From Dev

sqlalchemy one to many join in flask app to get max date

From Dev

sqlalchemy one to many join in flask app to get max date

From Dev

Yii2 hasMany with many conditions in join statement

From Dev

JOIN vs UNION vs IN() - big tables and many WHERE conditions

From Dev

mySQL JOIN on one to many

From Dev

Simplify many LINQ Join

From Dev

Simplify many LINQ Join

From Dev

join between two many-to-many tables

From Dev

SQL join on junction table with many to many relation

From Dev

Filter model, then join with many-to-many relation

Related Related

HotTag

Archive