--- /dev/null
+.. change::
+ :tags: bug, orm, regression
+ :tickets: 11625
+
+ Fixed regression appearing in 2.0.21 caused by :ticket:`10279` where using
+ a :func:`_sql.delete` or :func:`_sql.update` against an ORM class that is
+ the base of an inheritance hierarchy, while also specifying that subclasses
+ should be loaded polymorphically, would leak the polymorphic joins into the
+ UPDATE or DELETE statement as well creating incorrect SQL.
new_stmt = statement._clone()
+ if new_stmt.table._annotations["parententity"] is mapper:
+ new_stmt.table = mapper.local_table
+
# note if the statement has _multi_values, these
# are passed through to the new statement, which will then raise
# InvalidRequestError because UPDATE doesn't support multi_values
new_stmt = statement._clone()
+ if new_stmt.table._annotations["parententity"] is mapper:
+ new_stmt.table = mapper.local_table
+
new_crit = cls._adjust_for_extra_criteria(
self.global_attributes, mapper
)
from sqlalchemy.sql.selectable import Select
from sqlalchemy.testing import assert_raises
from sqlalchemy.testing import assert_raises_message
+from sqlalchemy.testing import AssertsCompiledSQL
from sqlalchemy.testing import eq_
from sqlalchemy.testing import expect_raises
from sqlalchemy.testing import fixtures
)
+class InheritWPolyTest(fixtures.TestBase, AssertsCompiledSQL):
+ __dialect__ = "default"
+
+ @testing.fixture
+ def inherit_fixture(self, decl_base):
+ def go(poly_type):
+
+ class Person(decl_base):
+ __tablename__ = "person"
+ id = Column(Integer, primary_key=True)
+ type = Column(String(50))
+ name = Column(String(50))
+
+ if poly_type.wpoly:
+ __mapper_args__ = {"with_polymorphic": "*"}
+
+ class Engineer(Person):
+ __tablename__ = "engineer"
+ id = Column(Integer, ForeignKey("person.id"), primary_key=True)
+ engineer_name = Column(String(50))
+
+ if poly_type.inline:
+ __mapper_args__ = {"polymorphic_load": "inline"}
+
+ return Person, Engineer
+
+ return go
+
+ @testing.variation("poly_type", ["wpoly", "inline", "none"])
+ def test_update_base_only(self, poly_type, inherit_fixture):
+ Person, Engineer = inherit_fixture(poly_type)
+
+ self.assert_compile(
+ update(Person).values(name="n1"), "UPDATE person SET name=:name"
+ )
+
+ @testing.variation("poly_type", ["wpoly", "inline", "none"])
+ def test_delete_base_only(self, poly_type, inherit_fixture):
+ Person, Engineer = inherit_fixture(poly_type)
+
+ self.assert_compile(delete(Person), "DELETE FROM person")
+
+ self.assert_compile(
+ delete(Person).where(Person.id == 7),
+ "DELETE FROM person WHERE person.id = :id_1",
+ )
+
+
class SingleTablePolymorphicTest(fixtures.DeclarativeMappedTest):
__backend__ = True