Filter on joined relationship not working for legacy Query objects
tstadel opened this issue · comments
Problem Description:
When trying to filter for a column on a join relationship on a legacy sqlalchemy Query
object, apply_odata_query
does not recognize existing join relationships ending up in a SQL statement that falsely joins the same relationship multiple times:
sqlalchemy.exc.ProgrammingError: (psycopg2.errors.DuplicateAlias) table name "my_relationship" specified more than once
Example code to reproduce:
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class MyRelationship(Base):
__tablename__ = "my_relationship"
relationship_id = Column(UUID(as_uuid=True), default=uuid.uuid4, primary_key=True, index=True, nullable=False)
some_bool = Column(Boolean, nullable=False)
some_other_bool = Column(Boolean, nullable=False)
class MyModel(Base):
__tablename__ = "my_model"
model_id = Column(UUID(as_uuid=True), default=uuid.uuid4, primary_key=True, index=True, nullable=False)
relationship_id = Column(
UUID(as_uuid=True),
ForeignKey(MyRelationship.relationship_id),
nullable=False,
)
my_relationship = relationship(MyRelationship)
from odata_query.sqlalchemy import apply_odata_query
orm_query = session.query(MyModel)
.select_from(MyModel)
.join(MyRelationship, MyModel.relationship_id == MyRelationship.relationship_id)
.filter(MyRelationship.some_bool == false()) # This is a SQLAlchemy Query object with existing join relationship
odata_query = "my_relationship/some_other_bool eq true" # we want to add a filter on the same relationship
query = apply_odata_query(orm_query, odata_query)
results = query.all() # this breaks
We found a solution by patching apply_odata_query
and _get_joined_attrs
. Would you mind if I raised a PR for that?
Thanks for reporting this and for the clear reproducing case.
Great that you already found a fix, and PR's are always appreciated!
Thanks for the contribution @tstadel!
I added a small integration test and released this in 0.8.1 🚀