Hello, I have a broken query when migrating from SQLAlchemy 0.9.4 to 1.0.12. It seems to be linked to a behavioral change in the ORM (http://docs.sqlalchemy.org/en/rel_1_0/changelog/migration_10.html#right-inner-join-nesting-now-the-default-for-joinedload-with-innerjoin-true)
Here is simplified version of the code: # -*- coding: utf-8 -*- from sqlalchemy import * from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import * Base = declarative_base() _plant_table = Table('plant', Base.metadata, Column('id', Integer, primary_key=True) ) _plant_dimensionsseries_table = Table('plant_dimensionsseries', Base. metadata, Column('plant_id', Integer, primary_key=True), Column('dimensionsseriestype_id', Integer, primary_key=True), ForeignKeyConstraint(['plant_id'], ['plant.id']) ) _view_plant_dimensionsseries_table = Table('view_plant_dimensionsseries', Base.metadata, Column('plant_id', Integer, primary_key=True), Column('dimensionsseriestype_id', Integer, primary_key=True), ForeignKeyConstraint( ['plant_id', 'dimensionsseriestype_id'], ['plant_dimensionsseries.plant_id', 'plant_dimensionsseries.dimensionsseriestype_id']) ) class Plant(Base): __table__ = _plant_table class PlantDimensionsseries(Base): __table__ = _plant_dimensionsseries_table _plant_id = __table__.c.plant_id _dimensionsseriestype_id = __table__.c.dimensionsseriestype_id plant = relationship('Plant', innerjoin=True, backref=backref('plant_dimensionsseries')) class PlantDimensionsseriesDataComputed(Base): __table__ = _view_plant_dimensionsseries_table _plant_id = __table__.c.plant_id _dimensionsseriestype_id = __table__.c.dimensionsseriestype_id # One-to-one relationship dimensionsseries = relationship('PlantDimensionsseries', innerjoin=True, backref=backref('data_computed', innerjoin=True)) if __name__ == '__main__': engine = create_engine( 'postgresql://nurseryacme_employee@localhost:5432/nurseryacme') Session = sessionmaker(bind=engine) session = Session() # query 1: # SQLAlchemy 0.9.4: Correct SQL generated # SQLAlchemy 1.0.12: Wrong SQL generated, a inner JOIN is used instead of a LEFT OUTER JOIN between plant_dimensionsseries and view_plant_dimensionsseries print session.query(Plant).\ outerjoin(Plant.plant_dimensionsseries).\ options(contains_eager(Plant.plant_dimensionsseries)).\ options(joinedload(Plant.plant_dimensionsseries, PlantDimensionsseries.data_computed)) # query 2: # SQLAlchemy 1.0.12: Correct SQL generated print session.query(Plant).\ outerjoin(Plant.plant_dimensionsseries).\ options(contains_eager(Plant.plant_dimensionsseries)).\ options(joinedload(Plant.plant_dimensionsseries, PlantDimensionsseries.data_computed, innerjoin=False)) Result with SQLAlchemy 0.9.4: # query 1 SELECT ... FROM plant LEFT OUTER JOIN plant_dimensionsseries ON plant.id = plant_dimensionsseries.plant_id *LEFT OUTER JOIN* view_plant_dimensionsseries AS view_plant_dimensionsseries_1 ON plant_dimensionsseries.plant_id = view_plant_dimensionsseries_1.plant_id AND plant_dimensionsseries.dimensionsseriestype_id = view_plant_dimensionsseries_1.dimensionsseriestype_id # query 2 SELECT ... FROM plant LEFT OUTER JOIN plant_dimensionsseries ON plant.id = plant_dimensionsseries.plant_id *LEFT OUTER JOIN* view_plant_dimensionsseries AS view_plant_dimensionsseries_1 ON plant_dimensionsseries.plant_id = view_plant_dimensionsseries_1.plant_id AND plant_dimensionsseries.dimensionsseriestype_id = view_plant_dimensionsseries_1.dimensionsseriestype_id Result with SQLAlchemy 1.0.12: # query 1 SELECT ... FROM plant LEFT OUTER JOIN plant_dimensionsseries ON plant.id = plant_dimensionsseries.plant_id *JOIN* view_plant_dimensionsseries AS view_plant_dimensionsseries_1 ON plant_dimensionsseries.plant_id = view_plant_dimensionsseries_1.plant_id AND plant_dimensionsseries.dimensionsseriestype_id = view_plant_dimensionsseries_1.dimensionsseriestype_id # query 2 SELECT ... FROM plant LEFT OUTER JOIN plant_dimensionsseries ON plant.id = plant_dimensionsseries.plant_id *LEFT OUTER JOIN* view_plant_dimensionsseries AS view_plant_dimensionsseries_1 ON plant_dimensionsseries.plant_id = view_plant_dimensionsseries_1.plant_id AND plant_dimensionsseries.dimensionsseriestype_id = view_plant_dimensionsseries_1.dimensionsseriestype_id In query 1 under SQLAlchemy 1.0.12, the query discard many rows due the JOIN chained to the LEFT OUTER JOIN and this precisely what SQLAlchemy wanted to avoid if I refer to the description of "Right-nested inner joins available in joined eager loads" (http://docs.sqlalchemy.org/en/rel_1_0/changelog/migration_09.html#feature-2976). I can fix the query 1 by adding the innerjoin=False as in query 2 but I am wondering if this is a bug or the expected behavior following the behavioral change in SQLAlchemy 1.0.x (http://docs.sqlalchemy.org/en/rel_1_0/changelog/migration_10.html#right-inner-join-nesting-now-the-default-for-joinedload-with-innerjoin-true). Is this a bug? -- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To unsubscribe from this group and stop receiving emails from it, send an email to sqlalchemy+unsubscr...@googlegroups.com. To post to this group, send email to sqlalchemy@googlegroups.com. Visit this group at https://groups.google.com/group/sqlalchemy. For more options, visit https://groups.google.com/d/optout.