Is it possible to query SQLAlchemy Joined Table Inheritance with and condition
Question:
Using flat models, it is possible to do the following join:
session.query( EmployeeModel.name, EmployeeDepartment.dept_name ).join( EmployeeDepartment, and_( EmployeeDepartment.employee_id == EmployeeModel.id, EmployeeDepartment.dept_code == 'P01' ) ).all()
In my case I have the following inheritance hierarchy:
`class Parent(Base):
tablename = ‘parent’
id = Column(BigInteger, primary_key=True)
cls = Column(String(255), nullable=False, index=True)
sub2_id = Column(ForeignKey('parent.id'),
unique=True)
extended_id = Column(
ForeignKey('extended.id'), index=True)
extended = relationship('Extended')
class Sub1(Parent):
tablename = ‘sub1’
sub1_id = Column(ForeignKey('parent.id'),
primary_key=True)
class Sub2(Sub1):
tablename = ‘sub2’
sub2_id = Column(
ForeignKey('sub1.sub1_id'), primary_key=True)
class Extented(Base):
tablename = ‘extended’
id = Column(BigInteger, primary_key=True)
classname = Column(String(255), nullable=False, index=True)
`
I am trying to achieve the following SQL native query:
SELECT sub2.sub2_id AS sub2_sub2_id FROM parent JOIN sub1 ON parent.id = sub1.sub1_id AND parent.cls = 'MAIN' JOIN sub2 ON sub1.sub1_id = sub2.sub2_id JOIN extended ON extended.id = parent.extended_id
But the following query result will be:
query = db.session.query(Sub2.sub2_id).join(Extented)
SELECT sub2.sub2_id AS sub2_sub2_id FROM parent JOIN sub1 ON parent.id = sub1.sub1_id JOIN sub2 ON sub1.sub1_id = sub2.sub2_id JOIN extended ON extended.id = parent.extended_id
Is it possible to customize the Models or relationship to achieve the desired query?
Appreciating your help.
I have tried adding the and condition to a relationship but that did not help.
Answers:
Yes, it is possible to customize the models and relationships in order to achieve the desired query. You can use the filter() method or the filter_by() method to add a filtering condition to the join.
Here’s an example of how you can use the filter() method to add a filtering condition to the join:
from sqlalchemy import and_
query = db.session.query(Sub2.sub2_id).join(Extented, and_(Parent.cls == 'MAIN', Parent.id == Sub1.sub1_id))
This will add the filtering condition Parent.cls = ‘MAIN’ and Parent.id = Sub1.sub1_id to the join, resulting in the desired query.
Alternatively, you can use the filter_by() method to add a filtering condition to the join:
query = db.session.query(Sub2.sub2_id).join(Extented).filter_by(cls='MAIN', id=Sub1.sub1_id)
This will have the same effect as the first example.
It’s important to note that the filter method and filter_by method are not only used in join, but you could use them to filter any query.
See more : https://docs.sqlalchemy.org/en/14/core/sqlelement.html
Using flat models, it is possible to do the following join:
session.query( EmployeeModel.name, EmployeeDepartment.dept_name ).join( EmployeeDepartment, and_( EmployeeDepartment.employee_id == EmployeeModel.id, EmployeeDepartment.dept_code == 'P01' ) ).all()
In my case I have the following inheritance hierarchy:
`class Parent(Base):
tablename = ‘parent’
id = Column(BigInteger, primary_key=True)
cls = Column(String(255), nullable=False, index=True)
sub2_id = Column(ForeignKey('parent.id'),
unique=True)
extended_id = Column(
ForeignKey('extended.id'), index=True)
extended = relationship('Extended')
class Sub1(Parent):
tablename = ‘sub1’
sub1_id = Column(ForeignKey('parent.id'),
primary_key=True)
class Sub2(Sub1):
tablename = ‘sub2’
sub2_id = Column(
ForeignKey('sub1.sub1_id'), primary_key=True)
class Extented(Base):
tablename = ‘extended’
id = Column(BigInteger, primary_key=True)
classname = Column(String(255), nullable=False, index=True)
`
I am trying to achieve the following SQL native query:
SELECT sub2.sub2_id AS sub2_sub2_id FROM parent JOIN sub1 ON parent.id = sub1.sub1_id AND parent.cls = 'MAIN' JOIN sub2 ON sub1.sub1_id = sub2.sub2_id JOIN extended ON extended.id = parent.extended_id
But the following query result will be:
query = db.session.query(Sub2.sub2_id).join(Extented)
SELECT sub2.sub2_id AS sub2_sub2_id FROM parent JOIN sub1 ON parent.id = sub1.sub1_id JOIN sub2 ON sub1.sub1_id = sub2.sub2_id JOIN extended ON extended.id = parent.extended_id
Is it possible to customize the Models or relationship to achieve the desired query?
Appreciating your help.
I have tried adding the and condition to a relationship but that did not help.
Yes, it is possible to customize the models and relationships in order to achieve the desired query. You can use the filter() method or the filter_by() method to add a filtering condition to the join.
Here’s an example of how you can use the filter() method to add a filtering condition to the join:
from sqlalchemy import and_
query = db.session.query(Sub2.sub2_id).join(Extented, and_(Parent.cls == 'MAIN', Parent.id == Sub1.sub1_id))
This will add the filtering condition Parent.cls = ‘MAIN’ and Parent.id = Sub1.sub1_id to the join, resulting in the desired query.
Alternatively, you can use the filter_by() method to add a filtering condition to the join:
query = db.session.query(Sub2.sub2_id).join(Extented).filter_by(cls='MAIN', id=Sub1.sub1_id)
This will have the same effect as the first example.
It’s important to note that the filter method and filter_by method are not only used in join, but you could use them to filter any query.
See more : https://docs.sqlalchemy.org/en/14/core/sqlelement.html