From 51eff5eb7abba446247f0f12428f07ccef1e0c1a Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sun, 7 Sep 2014 15:23:24 -0400 Subject: [PATCH] - changelog and migration for #3188, #3148. fixes #3188 fixes #3148 --- doc/build/changelog/changelog_10.rst | 27 +++++++++ doc/build/changelog/migration_10.rst | 82 +++++++++++++++++++++++++++- 2 files changed, 108 insertions(+), 1 deletion(-) diff --git a/doc/build/changelog/changelog_10.rst b/doc/build/changelog/changelog_10.rst index 55a2756598..cb7a9088dc 100644 --- a/doc/build/changelog/changelog_10.rst +++ b/doc/build/changelog/changelog_10.rst @@ -21,6 +21,33 @@ series as well. For changes that are specific to 1.0 with an emphasis on compatibility concerns, see :doc:`/changelog/migration_10`. + .. change:: + :tags: bug, orm + :tickets: 3148, 3188 + + A major rework to the behavior of expression labels, most + specifically when used with ColumnProperty constructs with + custom SQL expressions and in conjunction with the "order by + labels" logic first introduced in 0.9. Fixes include that an + ``order_by(Entity.some_col_prop)`` will now make use of "order by + label" rules even if Entity has been subject to aliasing, + either via inheritance rendering or via the use of the + ``aliased()`` construct; rendering of the same column property + multiple times with aliasing (e.g. ``query(Entity.some_prop, + entity_alias.some_prop)``) will label each occurrence of the + entity with a distinct label, and additionally "order by + label" rules will work for both (e.g. + ``order_by(Entity.some_prop, entity_alias.some_prop)``). + Additional issues that could prevent the "order by label" + logic from working in 0.9, most notably that the state of a + Label could change such that "order by label" would stop + working depending on how things were called, has been fixed. + + .. seealso:: + + :ref:`bug_3188` + + .. change:: :tags: bug, mysql :tickets: 3186 diff --git a/doc/build/changelog/migration_10.rst b/doc/build/changelog/migration_10.rst index 2b9e5f0fd5..6a48b31fa2 100644 --- a/doc/build/changelog/migration_10.rst +++ b/doc/build/changelog/migration_10.rst @@ -8,7 +8,7 @@ What's New in SQLAlchemy 1.0? undergoing maintenance releases as of May, 2014, and SQLAlchemy version 1.0, as of yet unreleased. - Document last updated: September 1, 2014 + Document last updated: September 7, 2014 Introduction ============ @@ -307,6 +307,86 @@ Renders:: :ticket:`3177` + +.. _bug_3188: + +ColumnProperty constructs work a lot better with aliases, order_by +------------------------------------------------------------------- + +A variety of issues regarding :func:`.column_property` have been fixed, +most specifically with regards to the :func:`.aliased` construct as well +as the "order by label" logic introduced in 0.9 (see :ref:`migration_1068`). + +Given a mapping like the following:: + + class A(Base): + __tablename__ = 'a' + + id = Column(Integer, primary_key=True) + + class B(Base): + __tablename__ = 'b' + + id = Column(Integer, primary_key=True) + a_id = Column(ForeignKey('a.id')) + + + A.b = column_property( + select([func.max(B.id)]).where(B.a_id == A.id).correlate(A) + ) + +A simple scenario that included "A.b" twice would fail to render +correctly:: + + print sess.query(A, a1).order_by(a1.b) + +This would order by the wrong column:: + + SELECT a.id AS a_id, (SELECT max(b.id) AS max_1 FROM b + WHERE b.a_id = a.id) AS anon_1, a_1.id AS a_1_id, + (SELECT max(b.id) AS max_2 + FROM b WHERE b.a_id = a_1.id) AS anon_2 + FROM a, a AS a_1 ORDER BY anon_1 + +New output:: + + SELECT a.id AS a_id, (SELECT max(b.id) AS max_1 + FROM b WHERE b.a_id = a.id) AS anon_1, a_1.id AS a_1_id, + (SELECT max(b.id) AS max_2 + FROM b WHERE b.a_id = a_1.id) AS anon_2 + FROM a, a AS a_1 ORDER BY anon_2 + +There were also many scenarios where the "order by" logic would fail +to order by label, for example if the mapping were "polymorphic":: + + class A(Base): + __tablename__ = 'a' + + id = Column(Integer, primary_key=True) + type = Column(String) + + __mapper_args__ = {'polymorphic_on': type, 'with_polymorphic': '*'} + +The order_by would fail to use the label, as it would be anonymized due +to the polymorphic loading:: + + SELECT a.id AS a_id, a.type AS a_type, (SELECT max(b.id) AS max_1 + FROM b WHERE b.a_id = a.id) AS anon_1 + FROM a ORDER BY (SELECT max(b.id) AS max_2 + FROM b WHERE b.a_id = a.id) + +Now that the order by label tracks the anonymized label, this now works:: + + SELECT a.id AS a_id, a.type AS a_type, (SELECT max(b.id) AS max_1 + FROM b WHERE b.a_id = a.id) AS anon_1 + FROM a ORDER BY anon_1 + +Included in these fixes are a variety of heisenbugs that could corrupt +the state of an ``aliased()`` construct such that the labeling logic +would again fail; these have also been fixed. + +:ticket:`3148` :ticket:`3188` + .. _behavioral_changes_orm_10: Behavioral Changes - ORM -- 2.47.3