summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2022-12-05 16:11:59 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2022-12-07 17:35:26 -0500
commit66c6b8558a6b64820b790199816acc66deffdacc (patch)
tree0e1c929fa8615d5042fad2a402c941b40d10b619 /test
parent59f5beff1928e752b33d65a541cd68295ae0a5f1 (diff)
downloadsqlalchemy-66c6b8558a6b64820b790199816acc66deffdacc.tar.gz
disable polymorphic adaption in most cases
Improved a fix first made in version 1.4 for :ticket:`8456` which scaled back the usage of internal "polymorphic adapters", that are used to render ORM queries when the :paramref:`_orm.Mapper.with_polymorphic` parameter is used. These adapters, which are very complex and error prone, are now used only in those cases where an explicit user-supplied subquery is used for :paramref:`_orm.Mapper.with_polymorphic`, which includes only the use case of concrete inheritance mappings that use the :func:`_orm.polymorphic_union` helper, as well as the legacy use case of using an aliased subquery for joined inheritance mappings, which is not needed in modern use. For the most common case of joined inheritance mappings that use the built-in polymorphic loading scheme, which includes those which make use of the :paramref:`_orm.Mapper.polymorphic_load` parameter set to ``inline``, polymorphic adapters are now no longer used. This has both a positive performance impact on the construction of queries as well as a substantial simplification of the internal query rendering process. The specific issue targeted was to allow a :func:`_orm.column_property` to refer to joined-inheritance classes within a scalar subquery, which now works as intuitively as is feasible. ORM context, mapper, strategies now use ORMAdapter in all cases instead of straight ColumnAdapter; added some more parameters to ORMAdapter to make this possible. ORMAdapter now includes a "trace" enumeration that identifies the use path for the adapter and can aid in debugging. implement __slots__ for the ExternalTraversal hierarchy up to ORMAdapter. Within this change, we have to change the ClauseAdapter.wrap() method, which is only used in one polymorphic codepath, to use copy.copy() instead of `__dict__` access (apparently `__reduce_ex__` is implemented for objects with `__slots__`), and we also remove pickling ability, which should not be needed for adapters (this might have been needed for 1.3 and earlier in order for Query to be picklable, but none of that state is present within Query / select() / etc. anymore). Fixes: #8168 Change-Id: I3f6593eb02ab5e5964807c53a9fa4894c826d017
Diffstat (limited to 'test')
-rw-r--r--test/orm/inheritance/test_assorted_poly.py35
1 files changed, 21 insertions, 14 deletions
diff --git a/test/orm/inheritance/test_assorted_poly.py b/test/orm/inheritance/test_assorted_poly.py
index 8ec36d299..4bebc9b10 100644
--- a/test/orm/inheritance/test_assorted_poly.py
+++ b/test/orm/inheritance/test_assorted_poly.py
@@ -30,7 +30,6 @@ from sqlalchemy.testing import AssertsExecutionResults
from sqlalchemy.testing import config
from sqlalchemy.testing import eq_
from sqlalchemy.testing import fixtures
-from sqlalchemy.testing import skip_test
from sqlalchemy.testing.fixtures import ComparableEntity
from sqlalchemy.testing.fixtures import fixture_session
from sqlalchemy.testing.provision import normalize_sequence
@@ -2411,7 +2410,7 @@ class Issue8168Test(AssertsCompiledSQL, fixtures.TestBase):
def mapping(self, decl_base):
Base = decl_base
- def go(scenario, use_poly):
+ def go(scenario, use_poly, use_poly_on_retailer):
class Customer(Base):
__tablename__ = "customer"
id = Column(Integer, primary_key=True)
@@ -2469,7 +2468,12 @@ class Issue8168Test(AssertsCompiledSQL, fixtures.TestBase):
.scalar_subquery()
)
- __mapper_args__ = {"polymorphic_identity": "retailer"}
+ __mapper_args__ = {
+ "polymorphic_identity": "retailer",
+ "polymorphic_load": "inline"
+ if use_poly_on_retailer
+ else None,
+ }
return Customer, Store, Retailer
@@ -2477,8 +2481,13 @@ class Issue8168Test(AssertsCompiledSQL, fixtures.TestBase):
@testing.variation("scenario", ["mapped_cls", "table", "table_alias"])
@testing.variation("use_poly", [True, False])
- def test_select_attr_only(self, scenario, use_poly, mapping):
- Customer, Store, Retailer = mapping(scenario, use_poly)
+ @testing.variation("use_poly_on_retailer", [True, False])
+ def test_select_attr_only(
+ self, scenario, use_poly, use_poly_on_retailer, mapping
+ ):
+ Customer, Store, Retailer = mapping(
+ scenario, use_poly, use_poly_on_retailer
+ )
if scenario.mapped_cls:
self.assert_compile(
@@ -2509,13 +2518,15 @@ class Issue8168Test(AssertsCompiledSQL, fixtures.TestBase):
@testing.variation("scenario", ["mapped_cls", "table", "table_alias"])
@testing.variation("use_poly", [True, False])
- def test_select_cls(self, scenario, mapping, use_poly):
- Customer, Store, Retailer = mapping(scenario, use_poly)
+ @testing.variation("use_poly_on_retailer", [True, False])
+ def test_select_cls(
+ self, scenario, mapping, use_poly, use_poly_on_retailer
+ ):
+ Customer, Store, Retailer = mapping(
+ scenario, use_poly, use_poly_on_retailer
+ )
if scenario.mapped_cls:
- # breaks for use_poly, but this is not totally unexpected
- if use_poly:
- skip_test("Case not working yet")
self.assert_compile(
select(Retailer),
"SELECT (SELECT count(store.id) AS count_1 FROM customer "
@@ -2525,10 +2536,6 @@ class Issue8168Test(AssertsCompiledSQL, fixtures.TestBase):
"FROM customer JOIN retailer ON customer.id = retailer.id",
)
elif scenario.table:
- # TODO: breaks for use_poly, and this should not happen.
- # selecting from the Table should be honoring that
- if use_poly:
- skip_test("Case not working yet")
self.assert_compile(
select(Retailer),
"SELECT (SELECT count(store.id) AS count_1 FROM store "