Esistono due tabelle in cui una colonna della tabella A indica la chiave primaria di un'altra tabella B.Come posso rendere il confronto delle proprietà in grado di essere compilato per l'espressione SQL in SQLAlchemy?
Ma sono inseriti in database diversi, quindi non posso configurarli con chiave esterna.
La configurazione tramite relationship()
non è disponibile, quindi ho implementato manualmente l'attributo di proprietà.
class User(Base):
__tablename__ = 'users'
id = Column(BigInteger, id_seq, primary=True)
name = Column(Unicode(256))
class Article(Base):
__tablename__ = 'articles'
__bind_key__ = 'another_engine'
# I am using custom session configures bind
# each mappers to multiple database engines via this attribute.
id = Column(BigInteger, id_seq, primary=True)
author_id = Column(BigInteger, nullable=False, index=True)
body = Column(UnicodeText, nullable=False)
@property
def author(self):
_session = object_session(self)
return _session.query(User).get(self.author_id)
@author.setter
def author(self, user):
if not isinstance(user, User):
raise TypeError('user must be a instance of User')
self.author_id = user.id
Questo codice funziona bene per operazioni semplici. Ma causa query sporche che rendono inutili le funzionalità di SQLAlchemy.
Il codice sarebbe semplice se fosse configurato tramite relationship()
(ad esempio query.filter(author=me)
) incasinato (ad esempio query.filter(author_id=me.id)
).
Le relazioni relative (ad esempio join) non possono mai essere utilizzate nella creazione di query.
Posso utilizzare l'attributo di proprietà, almeno, nella creazione del criterio di query (filter()/filter_by()
)?
Oh Grazie! join/joinload non può essere utilizzato perché la query compilata verrà eseguita in un singolo motore di database che viene mappato per l'esecuzione del mapping principale della query. ma l'accesso alla proprietà della relazione, utilizzandolo nell'espressione di filtro, funziona in modo sorprendente! – yoloseem