gorilla-co / odata-query

An OData v4 query parser and transpiler for Python

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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 🚀