Skip to content

Commit 2900c47

Browse files
zzzeekGerrit Code Review
authored andcommitted
Merge "qualify compile_state updates for non-current entities"
2 parents 5810f54 + 21f9a94 commit 2900c47

3 files changed

Lines changed: 94 additions & 11 deletions

File tree

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
.. change::
2+
:tags: bug, orm, regression
3+
:tickets: 6924
4+
5+
Fixed issue in recently repaired ``Query.with_entities()`` method where the
6+
flag that determines automatic uniquing for legacy ORM ``Query`` objects
7+
only would be set to ``True`` inappropriately in cases where the
8+
``with_entities()`` call would be setting the ``Query`` to return
9+
column-only rows, which are not uniqued.

lib/sqlalchemy/orm/context.py

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,10 @@ def create_for_statement(cls, statement_container, compiler, **kw):
417417
)
418418

419419
_QueryEntity.to_compile_state(
420-
self, statement_container._raw_columns, self._entities
420+
self,
421+
statement_container._raw_columns,
422+
self._entities,
423+
is_current_entities=True,
421424
)
422425

423426
self.current_path = statement_container._compile_options._current_path
@@ -590,14 +593,18 @@ def create_for_statement(cls, statement, compiler, **kw):
590593
self,
591594
memoized_entities._raw_columns,
592595
[],
596+
is_current_entities=False,
593597
)
594598
for memoized_entities in (
595599
select_statement._memoized_select_entities
596600
)
597601
}
598602

599603
_QueryEntity.to_compile_state(
600-
self, select_statement._raw_columns, self._entities
604+
self,
605+
select_statement._raw_columns,
606+
self._entities,
607+
is_current_entities=True,
601608
)
602609

603610
self.current_path = select_statement._compile_options._current_path
@@ -839,7 +846,9 @@ def _create_entities_collection(cls, query, legacy):
839846

840847
# entities will also set up polymorphic adapters for mappers
841848
# that have with_polymorphic configured
842-
_QueryEntity.to_compile_state(self, query._raw_columns, self._entities)
849+
_QueryEntity.to_compile_state(
850+
self, query._raw_columns, self._entities, is_current_entities=True
851+
)
843852
return self
844853

845854
@classmethod
@@ -2278,13 +2287,18 @@ class _QueryEntity(object):
22782287
use_id_for_hash = False
22792288

22802289
@classmethod
2281-
def to_compile_state(cls, compile_state, entities, entities_collection):
2290+
def to_compile_state(
2291+
cls, compile_state, entities, entities_collection, is_current_entities
2292+
):
22822293

22832294
for idx, entity in enumerate(entities):
22842295
if entity._is_lambda_element:
22852296
if entity._is_sequence:
22862297
cls.to_compile_state(
2287-
compile_state, entity._resolved, entities_collection
2298+
compile_state,
2299+
entity._resolved,
2300+
entities_collection,
2301+
is_current_entities,
22882302
)
22892303
continue
22902304
else:
@@ -2294,7 +2308,10 @@ def to_compile_state(cls, compile_state, entities, entities_collection):
22942308
if entity.is_selectable:
22952309
if "parententity" in entity._annotations:
22962310
_MapperEntity(
2297-
compile_state, entity, entities_collection
2311+
compile_state,
2312+
entity,
2313+
entities_collection,
2314+
is_current_entities,
22982315
)
22992316
else:
23002317
_ColumnEntity._for_columns(
@@ -2343,12 +2360,15 @@ class _MapperEntity(_QueryEntity):
23432360
"_polymorphic_discriminator",
23442361
)
23452362

2346-
def __init__(self, compile_state, entity, entities_collection):
2363+
def __init__(
2364+
self, compile_state, entity, entities_collection, is_current_entities
2365+
):
23472366
entities_collection.append(self)
2348-
if compile_state._primary_entity is None:
2349-
compile_state._primary_entity = self
2350-
compile_state._has_mapper_entities = True
2351-
compile_state._has_orm_entities = True
2367+
if is_current_entities:
2368+
if compile_state._primary_entity is None:
2369+
compile_state._primary_entity = self
2370+
compile_state._has_mapper_entities = True
2371+
compile_state._has_orm_entities = True
23522372

23532373
entity = entity._annotations["parententity"]
23542374
entity._post_inspect

test/orm/test_froms.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
from sqlalchemy.orm import mapper
3030
from sqlalchemy.orm import relationship
3131
from sqlalchemy.orm import Session
32+
from sqlalchemy.orm.context import ORMSelectCompileState
3233
from sqlalchemy.orm.util import join
3334
from sqlalchemy.sql import column
3435
from sqlalchemy.sql import table
@@ -1699,6 +1700,59 @@ def test_correlated_subquery(self):
16991700
],
17001701
)
17011702

1703+
@testing.combinations((True,), (False,))
1704+
def test_no_uniquing_cols_legacy(self, with_entities):
1705+
"""test #6924"""
1706+
User = self.classes.User
1707+
Address = self.classes.Address
1708+
1709+
sess = fixture_session()
1710+
1711+
if with_entities:
1712+
q = (
1713+
sess.query(User)
1714+
.join(Address)
1715+
.filter(Address.user_id == 8)
1716+
.with_entities(User.id, User.name)
1717+
.order_by(User.id)
1718+
)
1719+
else:
1720+
q = (
1721+
sess.query(User.id, User.name)
1722+
.join(Address)
1723+
.filter(Address.user_id == 8)
1724+
.order_by(User.id)
1725+
)
1726+
1727+
is_(q._compile_state()._primary_entity, None)
1728+
1729+
eq_(q.all(), [(8, "ed"), (8, "ed"), (8, "ed")])
1730+
1731+
@testing.combinations((True,), (False,))
1732+
def test_no_uniquing_cols(self, with_entities):
1733+
"""test #6924"""
1734+
User = self.classes.User
1735+
Address = self.classes.Address
1736+
1737+
if with_entities:
1738+
stmt = (
1739+
select(User)
1740+
.join(Address)
1741+
.filter(Address.user_id == 8)
1742+
.with_only_columns(User.id, User.name)
1743+
.order_by(User.id)
1744+
)
1745+
else:
1746+
stmt = (
1747+
select(User.id, User.name)
1748+
.join(Address)
1749+
.filter(Address.user_id == 8)
1750+
.order_by(User.id)
1751+
)
1752+
1753+
compile_state = ORMSelectCompileState.create_for_statement(stmt, None)
1754+
is_(compile_state._primary_entity, None)
1755+
17021756
def test_column_queries_one(self):
17031757
User = self.classes.User
17041758

0 commit comments

Comments
 (0)