contains_eager() silently ignored when using specific polymorphic model (failing unit test inside)
See original GitHub issueWe are observing a silently ignored contains_eager()
definition in the following example, formatted into a simple unit test which is failing with SQLAlchemy==1.3.12
:
from re import match
from unittest import TestCase
from sqlalchemy import Column, create_engine, ForeignKey, Integer, String
from sqlalchemy.dialects import postgresql
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import aliased, contains_eager, relationship, sessionmaker
class TestEagerLoad(TestCase):
def test_eager_load(self):
Base = declarative_base()
class X(Base):
__tablename__ = 'x'
id = Column(Integer, primary_key=True)
a_id = Column(Integer, ForeignKey('a.id'))
a = relationship('A', back_populates='x')
class A(Base):
__tablename__ = 'a'
id = Column(Integer, primary_key=True)
b = relationship('B', back_populates='a')
kind = Column(String)
x = relationship('X', back_populates='a')
__mapper_args__ = {
'polymorphic_identity': 'a',
'polymorphic_on': kind,
'with_polymorphic': '*',
}
class B(A):
a_id = Column(Integer, ForeignKey('a.id'))
a = relationship('A', back_populates='b', uselist=False, remote_side=A.id)
__mapper_args__ = {
'polymorphic_identity': 'b',
}
engine = create_engine('sqlite://')
Base.metadata.create_all(engine)
session = sessionmaker(bind=engine)()
a_x_alias = aliased(X, name='a_x')
a_b_alias = aliased(B, name='a_b')
b_x_alias = aliased(X, name='b_x')
q = (
session
.query(A)
.outerjoin(A.x.of_type(a_x_alias))
.options(contains_eager(A.x.of_type(a_x_alias)))
.outerjoin(A.b.of_type(a_b_alias))
.outerjoin(a_b_alias.x.of_type(b_x_alias))
.options(
contains_eager(A.b.of_type(a_b_alias))
.contains_eager(a_b_alias.x.of_type(b_x_alias)) # !!! Without effect !!!
)
)
s = str(q.statement.compile(
dialect=postgresql.dialect(), compile_kwargs={"literal_binds": True}
)).replace('\n', '')
print(s)
self.assertCountEqual(
[i.strip() for i in match(r'SELECT(.*)FROM', s).group(1).split(',')],
[
'a.id',
'a.a_id',
'a.kind',
'a_x.id',
'a_x.a_id',
'a_b.id',
'a_b.a_id',
'a_b.kind',
'b_x.id',
'b_x.a_id',
]
)
with:
E AssertionError: Element counts were not equal:
E First has 0, Second has 1: 'b_x.id'
E First has 0, Second has 1: 'b_x.a_id'
which is surprising because the eager-loading of b_x
is properly specified to my understanding.
The generated query is the following:
SELECT a_b.id, a_b.kind, a_b.a_id, a_x.id, a_x.a_id, a.id, a.kind, a.a_id
FROM a
LEFT OUTER JOIN x AS a_x ON a.id = a_x.a_id
LEFT OUTER JOIN a AS a_b ON a.id = a_b.a_id AND a_b.kind IN ('b')
LEFT OUTER JOIN x AS b_x ON a_b.id = b_x.a_id
We however expected this query to be generated:
SELECT a_b.id, a_b.kind, a_b.a_id, a_x.id, a_x.a_id, a.id, a.kind, a.a_id, b_x.id, b_x.id
FROM a
LEFT OUTER JOIN x AS a_x ON a.id = a_x.a_id
LEFT OUTER JOIN a AS a_b ON a.id = a_b.a_id AND a_b.kind IN ('b')
LEFT OUTER JOIN x AS b_x ON a_b.id = b_x.a_id
Issue Analytics
- State:
- Created 4 years ago
- Comments:7 (3 by maintainers)
Top Results From Across the Web
Conditionally ignoring tests in JUnit 4 - java - Stack Overflow
To fail the test, use org.junit.Assert.fail() inside the conditional statement. Works same like Assume.assumeTrue() but fails the test.
Read more >unittest — Unit testing framework — Python 3.11.1 ...
The crux of each test is a call to assertEqual() to check for an expected result; assertTrue() or assertFalse() to verify a condition;...
Read more >Exception when trying to use InMemoryDatabase for unit testing
I'm trying to get xUnit working with EF's InMemoryDatabase but I'm ... are silently being ignored in tests (because InMemory is being used), ......
Read more >Three Reasons Why We Should Not Use Inheritance In Our ...
If we use inheritance in our tests, it can have a negative effect to the performance of our test suite. In order to...
Read more >Goto Fail, Heartbleed, and Unit Testing Culture - Martin Fowler
This article considers the role unit testing could play, showing how unit tests, and more importantly a unit testing culture, could have identified...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Thank you Mike. PS: I donated a few bucks to your PayPal.
thank you very much !!