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