<p dir="auto"><strong>Migrated issue, originally created by Kent Rakip (<a href="https://github.com/krakip">@krakip</a>)</strong></p>
<p dir="auto">When a <code class="notranslate">joinedload</code> path causes any entity in a one-to-many relationship to be eagerly loaded, any <code class="notranslate">subqueryload</code> path for the same relationship will not be emitted, even if it might return additional results.</p>
<p dir="auto">Here is a minimal repro case:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="from sqlalchemy import Column, ForeignKey, Integer, create_engine, inspect
from sqlalchemy.orm import relationship, sessionmaker, joinedload
from sqlalchemy.ext.declarative import declarative_base


Base = declarative_base()


class Thing(Base):
    __tablename__ = 'Thing'

    id = Column(Integer, primary_key=True, autoincrement=True)
    another_thing_id = Column(ForeignKey('AnotherThing.id'))
    another_thing = relationship('AnotherThing')

    yet_another_thing_id = Column(ForeignKey('YetAnotherThing.id'))
    yet_another_thing = relationship('YetAnotherThing')


class AnotherThing(Base):
    __tablename__ = 'AnotherThing'

    id = Column(Integer, primary_key=True, autoincrement=True)


class YetAnotherThing(Base):
    __tablename__ = 'YetAnotherThing'

    id = Column(Integer, primary_key=True, autoincrement=True)

    another_thing_id = Column(ForeignKey('AnotherThing.id'))
    another_thing = relationship('AnotherThing', backref='yet_another_things')
    last_thing_id = Column(ForeignKey('LastThing.id'))
    last_thing = relationship('LastThing')


class LastThing(Base):
    __tablename__ = 'LastThing'

    id = Column(Integer, primary_key=True, autoincrement=True)


engine = create_engine('sqlite:///', echo=True)
Base.metadata.create_all(engine)
session_factory = sessionmaker(bind=engine)

session = session_factory()

thing = Thing()
thing.another_thing = AnotherThing()
thing.another_thing.yet_another_things = [YetAnotherThing(), YetAnotherThing()]
thing.yet_another_thing = thing.another_thing.yet_another_things[0]
thing.another_thing.yet_another_things[0].last_thing = LastThing()
thing.another_thing.yet_another_things[1].last_thing = LastThing()

session.add(thing)
session.commit()

session2 = session_factory()

t = (
    session2.query(Thing)
        .options(
            joinedload(Thing.another_thing)
                .subqueryload(AnotherThing.yet_another_things)
                .joinedload(YetAnotherThing.last_thing),
            joinedload(Thing.yet_another_thing)
                .joinedload(YetAnotherThing.another_thing),
        )
        .get(1)
)

# Should print 'False'; actually prints 'True' on 1.1.4
print('yet_another_things' in inspect(t.another_thing).unloaded)"><pre class="notranslate"><code class="notranslate">from sqlalchemy import Column, ForeignKey, Integer, create_engine, inspect
from sqlalchemy.orm import relationship, sessionmaker, joinedload
from sqlalchemy.ext.declarative import declarative_base


Base = declarative_base()


class Thing(Base):
    __tablename__ = 'Thing'

    id = Column(Integer, primary_key=True, autoincrement=True)
    another_thing_id = Column(ForeignKey('AnotherThing.id'))
    another_thing = relationship('AnotherThing')

    yet_another_thing_id = Column(ForeignKey('YetAnotherThing.id'))
    yet_another_thing = relationship('YetAnotherThing')


class AnotherThing(Base):
    __tablename__ = 'AnotherThing'

    id = Column(Integer, primary_key=True, autoincrement=True)


class YetAnotherThing(Base):
    __tablename__ = 'YetAnotherThing'

    id = Column(Integer, primary_key=True, autoincrement=True)

    another_thing_id = Column(ForeignKey('AnotherThing.id'))
    another_thing = relationship('AnotherThing', backref='yet_another_things')
    last_thing_id = Column(ForeignKey('LastThing.id'))
    last_thing = relationship('LastThing')


class LastThing(Base):
    __tablename__ = 'LastThing'

    id = Column(Integer, primary_key=True, autoincrement=True)


engine = create_engine('sqlite:///', echo=True)
Base.metadata.create_all(engine)
session_factory = sessionmaker(bind=engine)

session = session_factory()

thing = Thing()
thing.another_thing = AnotherThing()
thing.another_thing.yet_another_things = [YetAnotherThing(), YetAnotherThing()]
thing.yet_another_thing = thing.another_thing.yet_another_things[0]
thing.another_thing.yet_another_things[0].last_thing = LastThing()
thing.another_thing.yet_another_things[1].last_thing = LastThing()

session.add(thing)
session.commit()

session2 = session_factory()

t = (
    session2.query(Thing)
        .options(
            joinedload(Thing.another_thing)
                .subqueryload(AnotherThing.yet_another_things)
                .joinedload(YetAnotherThing.last_thing),
            joinedload(Thing.yet_another_thing)
                .joinedload(YetAnotherThing.another_thing),
        )
        .get(1)
)

# Should print 'False'; actually prints 'True' on 1.1.4
print('yet_another_things' in inspect(t.another_thing).unloaded)
</code></pre></div>
<p dir="auto">The query that should load all of the values for <code class="notranslate">AnotherThing.yet_another_things</code> is never emitted, and as a result <code class="notranslate">last_thing</code> is not loaded for any of the <code class="notranslate">YetAnotherThing</code>s either, since that occurs later on the same path. Commenting out the second <code class="notranslate">joinedload</code> path causes the <code class="notranslate">subqueryload</code> query to be emitted correctly.</p>
<p dir="auto">This seems to be a regression in 1.1; I'm unable to reproduce it on 1.0.16, although it is possible that the behavior is nondeterministic and I never got lucky.</p>
<p dir="auto"><strong>Migrated issue, originally created by Sebastian Bank (<a href="https://github.com/xflr6">@xflr6</a>)</strong></p>
<p dir="auto">Currently, reuse of a value for <code class="notranslate">polymorphic_identity</code> just overwrites the old mapping.<br>
This can lead hard to debug failiures (queried instances having unexpected types):</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="from sqlalchemy import create_engine, Column, Integer, String, ForeignKey
from sqlalchemy.orm import Session
from sqlalchemy.ext.declarative import declarative_base


class Spam(declarative_base()):

    __tablename__ = 'spam'

    id = Column(Integer, primary_key=True)
    
    kind = Column(String)

    __mapper_args__ = {'polymorphic_on': kind, 'polymorphic_identity': 'spam'}


class Eggs(Spam):

   __tablename__ = 'eggs'

   id = Column(Integer, ForeignKey('spam.id'), primary_key=True)

   __mapper_args__ = {'polymorphic_identity': 'spam'}  # warn here


engine = create_engine('sqlite://')

Spam.metadata.create_all(engine)

session = Session(engine)

session.add(Spam())
session.flush()
spam = session.query(Spam).one()

assert type(spam) is Spam  # fails"><pre class="notranslate"><span class="pl-k">from</span> <span class="pl-s1">sqlalchemy</span> <span class="pl-k">import</span> <span class="pl-s1">create_engine</span>, <span class="pl-v">Column</span>, <span class="pl-v">Integer</span>, <span class="pl-v">String</span>, <span class="pl-v">ForeignKey</span>
<span class="pl-k">from</span> <span class="pl-s1">sqlalchemy</span>.<span class="pl-s1">orm</span> <span class="pl-k">import</span> <span class="pl-v">Session</span>
<span class="pl-k">from</span> <span class="pl-s1">sqlalchemy</span>.<span class="pl-s1">ext</span>.<span class="pl-s1">declarative</span> <span class="pl-k">import</span> <span class="pl-s1">declarative_base</span>


<span class="pl-k">class</span> <span class="pl-v">Spam</span>(<span class="pl-en">declarative_base</span>()):

    <span class="pl-s1">__tablename__</span> <span class="pl-c1">=</span> <span class="pl-s">'spam'</span>

    <span class="pl-s1">id</span> <span class="pl-c1">=</span> <span class="pl-v">Column</span>(<span class="pl-v">Integer</span>, <span class="pl-s1">primary_key</span><span class="pl-c1">=</span><span class="pl-c1">True</span>)
    
    <span class="pl-s1">kind</span> <span class="pl-c1">=</span> <span class="pl-v">Column</span>(<span class="pl-v">String</span>)

    <span class="pl-s1">__mapper_args__</span> <span class="pl-c1">=</span> {<span class="pl-s">'polymorphic_on'</span>: <span class="pl-s1">kind</span>, <span class="pl-s">'polymorphic_identity'</span>: <span class="pl-s">'spam'</span>}


<span class="pl-k">class</span> <span class="pl-v">Eggs</span>(<span class="pl-v">Spam</span>):

   <span class="pl-s1">__tablename__</span> <span class="pl-c1">=</span> <span class="pl-s">'eggs'</span>

   <span class="pl-s1">id</span> <span class="pl-c1">=</span> <span class="pl-v">Column</span>(<span class="pl-v">Integer</span>, <span class="pl-v">ForeignKey</span>(<span class="pl-s">'spam.id'</span>), <span class="pl-s1">primary_key</span><span class="pl-c1">=</span><span class="pl-c1">True</span>)

   <span class="pl-s1">__mapper_args__</span> <span class="pl-c1">=</span> {<span class="pl-s">'polymorphic_identity'</span>: <span class="pl-s">'spam'</span>}  <span class="pl-c"># warn here</span>


<span class="pl-s1">engine</span> <span class="pl-c1">=</span> <span class="pl-en">create_engine</span>(<span class="pl-s">'sqlite://'</span>)

<span class="pl-v">Spam</span>.<span class="pl-s1">metadata</span>.<span class="pl-en">create_all</span>(<span class="pl-s1">engine</span>)

<span class="pl-s1">session</span> <span class="pl-c1">=</span> <span class="pl-v">Session</span>(<span class="pl-s1">engine</span>)

<span class="pl-s1">session</span>.<span class="pl-en">add</span>(<span class="pl-v">Spam</span>())
<span class="pl-s1">session</span>.<span class="pl-en">flush</span>()
<span class="pl-s1">spam</span> <span class="pl-c1">=</span> <span class="pl-s1">session</span>.<span class="pl-en">query</span>(<span class="pl-v">Spam</span>).<span class="pl-en">one</span>()

<span class="pl-k">assert</span> <span class="pl-en">type</span>(<span class="pl-s1">spam</span>) <span class="pl-c1">is</span> <span class="pl-v">Spam</span>  <span class="pl-c"># fails</span></pre></div>
<p dir="auto">Provided there is no use case for overwriting, it would be nice to make the user aware of such misconfiguration at an early development stage.</p>