Commits

Mike Bayer  committed 00f151d Merge

merge latest default

  • Participants
  • Parent commits ac0404d, d30e4f3

Comments (0)

Files changed (41)

File doc/build/changelog/changelog_07.rst

 0.7 Changelog
 ==============
 
-                
+
 .. changelog::
     :version: 0.7.10
-    :released: 
+    :released:
+
+    .. change::
+        :tags: oracle, bug
+        :tickets: 2620
+
+      The Oracle LONG type, while an unbounded text type, does not appear
+      to use the cx_Oracle.LOB type when result rows are returned,
+      so the dialect has been repaired to exclude LONG from
+      having cx_Oracle.LOB filtering applied.
+
+    .. change::
+        :tags: oracle, bug
+        :tickets: 2611
+
+      Repaired the usage of ``.prepare()`` in conjunction with
+      cx_Oracle so that a return value of ``False`` will result
+      in no call to ``connection.commit()``, hence avoiding
+      "no transaction" errors.   Two-phase transactions have
+      now been shown to work in a rudimental fashion with
+      SQLAlchemy and cx_oracle, however are subject to caveats
+      observed with the driver; check the documentation
+      for details.
+
+    .. change::
+        :tags: orm, bug
+        :tickets: 2624
+
+      The :class:`.MutableComposite` type did not allow for the
+      :meth:`.MutableBase.coerce` method to be used, even though
+      the code seemed to indicate this intent, so this now works
+      and a brief example is added.  As a side-effect,
+      the mechanics of this event handler have been changed so that
+      new :class:`.MutableComposite` types no longer add per-type
+      global event handlers.  Also in 0.8.0b2.
 
     .. change::
         :tags: orm, bug
 
     .. change::
         :tags: orm, bug
-        :tickets: 
+        :tickets:
 
       Fixed bug mostly local to new
       AbstractConcreteBase helper where the "type"
 
     .. change::
         :tags: orm, bug
-        :tickets: 
+        :tickets:
 
       A warning is emitted when lazy='dynamic'
       is combined with uselist=False.  This is an
 
     .. change::
         :tags: orm, bug
-        :tickets: 
+        :tickets:
 
       Fixed bug whereby user error in related-object
       assignment could cause recursion overflow if the
 
     .. change::
         :tags: bug, sql
-        :tickets: 
+        :tickets:
 
       Fixed more un-intuitivenesses in CTEs
       which prevented referring to a CTE in a union
 
     .. change::
         :tags: engine, bug
-        :tickets: 
+        :tickets:
 
       Fixed the repr() of Enum to include
       the "name" and "native_enum" flags.  Helps
 
     .. change::
         :tags: sqlite, feature
-        :tickets: 
+        :tickets:
 
       Added support for the localtimestamp()
       SQL function implemented in SQLite, courtesy
 
     .. change::
         :tags: bug, mysql
-        :tickets: 
+        :tickets:
 
       Updated mysqlconnector interface to use
       updated "client flag" and "charset" APIs,
 
     .. change::
         :tags: mssql, bug
-        :tickets: 
+        :tickets:
 
       Fixed bug where reflection of primary key constraint
       would double up columns if the same constraint/table
 
     .. change::
         :tags: orm, feature
-        :tickets: 
+        :tickets:
 
       The 'objects' argument to
       flush() is no longer deprecated, as some
 
     .. change::
         :tags: orm, feature
-        :tickets: 
+        :tickets:
 
       Added new flag to @validates
       include_removes.  When True, collection
 
     .. change::
         :tags: orm, bug
-        :tickets: 
+        :tickets:
 
       Fixed bug in relationship comparisons
       whereby calling unimplemented methods like
 
     .. change::
         :tags: bug, sql
-        :tickets: 
+        :tickets:
 
       Removed warning when Index is created
       with no columns; while this might not be what
 
     .. change::
         :tags: feature, sql
-        :tickets: 
+        :tickets:
 
       Added new connection event
       dbapi_error(). Is called for all DBAPI-level
 
     .. change::
         :tags: bug, sql
-        :tickets: 
+        :tickets:
 
       If conn.begin() fails when calling
       "with engine.begin()", the newly acquired
 
     .. change::
         :tags: mssql, feature
-        :tickets: 
+        :tickets:
 
       Added interim create_engine flag
       supports_unicode_binds to PyODBC dialect,
 
     .. change::
         :tags: mssql, bug
-        :tickets: 
+        :tickets:
 
       Repaired the use_scope_identity
       create_engine() flag when using the pyodbc
 
     .. change::
         :tags: bug, mysql
-        :tickets: 
+        :tickets:
 
       Fixed bug whereby get_view_names() for
       "information_schema" schema would fail
 
     .. change::
         :tags: orm, feature
-        :tickets: 
+        :tickets:
 
       Added "no_autoflush" context
       manager to Session, used with with:
 
     .. change::
         :tags: orm, bug
-        :tickets: 
+        :tickets:
 
       Improved the "declarative reflection"
       example to support single-table inheritance,
 
     .. change::
         :tags: engine, bug
-        :tickets: 
+        :tickets:
 
       Added execution_options() call to
       MockConnection (i.e., that used with
 
     .. change::
         :tags: engine, feature
-        :tickets: 
+        :tickets:
 
       Added some decent context managers
       to Engine, Connection:
-      
+
           with engine.begin() as conn:
               <work with conn in a transaction>
-      
+
       and:
-      
+
           with engine.connect() as conn:
               <work with conn>
-      
+
       Both close out the connection when done,
       commit or rollback transaction with errors
       on engine.begin().
 
     .. change::
         :tags: examples, bug
-        :tickets: 
+        :tickets:
 
       Altered _params_from_query() function
       in Beaker example to pull bindparams from the
 
     .. change::
         :tags: orm, feature
-        :tickets: 
+        :tickets:
 
       Added "class_registry" argument to
       declarative_base().  Allows two or more declarative
 
     .. change::
         :tags: orm, feature
-        :tickets: 
+        :tickets:
 
       query.filter() accepts multiple
       criteria which will join via AND, i.e.
 
     .. change::
         :tags: orm, bug
-        :tickets: 
+        :tickets:
 
       Fixed bug whereby hybrid_property didn't
       work as a kw arg in any(), has().
 
     .. change::
         :tags: orm
-        :tickets: 
+        :tickets:
 
       Fixed regression from 0.6 whereby if
       "load_on_pending" relationship() flag were used
 
     .. change::
         :tags: feature, sql
-        :tickets: 
+        :tickets:
 
       Added "false()" and "true()" expression
       constructs to sqlalchemy.sql namespace, though
 
     .. change::
         :tags: sqlite, bug
-        :tickets: 
+        :tickets:
 
       removed an erroneous "raise" in the
       SQLite dialect when getting table names
 
       polymorphic_on now accepts many
       new kinds of values:
-      
+
         - standalone expressions that aren't
           otherwise mapped
         - column_property() objects
         - string names of any column_property()
           or attribute name of a mapped Column
-      
+
       The docs include an example using
       the case() construct, which is likely to be
       a common constructed used here. and part of
-      
+
       Standalone expressions in polymorphic_on
       propagate to single-table inheritance
       subclasses so that they are used in the
 
     .. change::
         :tags: orm, feature
-        :tickets: 
+        :tickets:
 
       Added new value for Column autoincrement
       called "ignore_fk", can be used to force autoincrement
 
     .. change::
         :tags: orm, bug
-        :tickets: 
+        :tickets:
 
       Fixed bug in get_history() when referring
       to a composite attribute that has no value;
 
     .. change::
         :tags: feature, schema
-        :tickets: 
+        :tickets:
 
       Added new support for remote "schemas":
 
     .. change::
         :tags: schema
-        :tickets: 
+        :tickets:
 
       MetaData() accepts "schema" and "quote_schema"
       arguments, which will be applied to the same-named
 
     .. change::
         :tags: schema
-        :tickets: 
+        :tickets:
 
       Sequence accepts "quote_schema" argument
 
     .. change::
         :tags: schema
-        :tickets: 
+        :tickets:
 
       tometadata() for Table will use the "schema"
       of the incoming MetaData for the new Table
 
     .. change::
         :tags: schema
-        :tickets: 
+        :tickets:
 
       Added CreateSchema and DropSchema DDL
       constructs - these accept just the string
 
     .. change::
         :tags: schema
-        :tickets: 
+        :tickets:
 
       When using default "schema" with MetaData,
       ForeignKey will also assume the "default" schema
 
     .. change::
         :tags: bug, schema
-        :tickets: 
+        :tickets:
 
       Fixed bug whereby TypeDecorator would
       return a stale value for _type_affinity, when
 
     .. change::
         :tags: bug, schema
-        :tickets: 
+        :tickets:
 
       Fixed bug whereby "order_by='foreign_key'"
       option to Inspector.get_table_names
 
     .. change::
         :tags: postgresql, feature
-        :tickets: 
+        :tickets:
 
       Added create_type constructor argument
       to pg.ENUM.  When False, no CREATE/DROP or
 
     .. change::
         :tags: bug, mysql
-        :tickets: 
+        :tickets:
 
       Unicode adjustments allow latest pymysql
       (post 0.4) to pass 100% on Python 2.
 
     .. change::
         :tags: ext, feature
-        :tickets: 
+        :tickets:
 
       Added an example to the hybrid docs
       of a "transformer" - a hybrid that returns a
 
     .. change::
         :tags: ext, bug
-        :tickets: 
+        :tickets:
 
       the @compiles decorator raises an
       informative error message when no "default"
 
     .. change::
         :tags: examples, bug
-        :tickets: 
+        :tickets:
 
       Fixed bug in history_meta.py example where
       the "unique" flag was not removed from a
 
     .. change::
         :tags: orm
-        :tickets: 
+        :tickets:
 
       added "adapt_on_names" boolean flag to orm.aliased()
       construct.  Allows an aliased() construct
 
     .. change::
         :tags: orm
-        :tickets: 
+        :tickets:
 
       Added new flag expire_on_flush=False to column_property(),
       marks those properties that would otherwise be considered
 
     .. change::
         :tags: orm
-        :tickets: 
+        :tickets:
 
       Fixed a variety of synonym()-related regressions
       from 0.6:
 
     .. change::
         :tags: orm
-        :tickets: 
+        :tickets:
 
       Query will convert an OFFSET of zero when
       slicing into None, so that needless OFFSET
 
     .. change::
         :tags: orm
-        :tickets: 
+        :tickets:
 
       Repaired edge case where mapper would fail
       to fully update internal state when a relationship
 
       Fixed bug whereby if __eq__() was
       redefined, a relationship many-to-one lazyload
-      would hit the __eq__() and fail. 
+      would hit the __eq__() and fail.
       Does not apply to 0.6.9.
 
     .. change::
 
     .. change::
         :tags: orm
-        :tickets: 
+        :tickets:
 
       New event hook, MapperEvents.after_configured().
       Called after a configure() step has completed and
 
     .. change::
         :tags: engine
-        :tickets: 
+        :tickets:
 
       Added optional "sa_pool_key" argument to
       pool.manage(dbapi).connect() so that serialization
 
     .. change::
         :tags: sqlite
-        :tickets: 
+        :tickets:
 
       Ensured that the same ValueError is raised for
       illegal date/time/datetime string parsed from
 
     .. change::
         :tags: postgresql
-        :tickets: 
+        :tickets:
 
       Use an atomic counter as the "random number"
       source for server side cursor names;
 
       Adjusted dictlike-polymorphic.py example
       to apply the CAST such that it works on
-      PG, other databases. 
+      PG, other databases.
       Also in 0.6.9.
 
 .. changelog::
       from a joined-inh structure to itself on
       relationship() with join condition on the child
       table would convert the lead entity into the
-      joined one inappropriately. 
+      joined one inappropriately.
       Also in 0.6.9.
 
     .. change::
       sorting of persistent + pending objects during
       flush would produce an illegal comparison,
       if the persistent object primary key
-      is not a single integer. 
+      is not a single integer.
       Also in 0.6.9
 
     .. change::
       Fixed bug whereby the source clause
       used by query.join() would be inconsistent
       if against a column expression that combined
-      multiple entities together. 
+      multiple entities together.
       Also in 0.6.9
 
     .. change::
       as SQLA should never consult these,
       the methods would be consulted if the class
       was part of a "composite" (i.e. non-single-entity)
-      result set. 
+      result set.
       Also in 0.6.9.
 
     .. change::
 
     .. change::
         :tags: orm
-        :tickets: 
+        :tickets:
 
       Added the same "columns-only" check to
       mapper.polymorphic_on as used when
 
     .. change::
         :tags: schema
-        :tickets: 
+        :tickets:
 
       Added an informative error message when
       ForeignKeyConstraint refers to a column name in
 
     .. change::
         :tags: schema
-        :tickets: 
+        :tickets:
 
       Fixed bug where "autoincrement" detection on
       Table would fail if the type had no "affinity"
 
     .. change::
         :tags: engine
-        :tickets: 
+        :tickets:
 
       Context manager provided by Connection.begin()
       will issue rollback() if the commit() fails,
 
     .. change::
         :tags: engine
-        :tickets: 
+        :tickets:
 
       Added mixin class sqlalchemy.ext.DontWrapMixin.
       User-defined exceptions of this type are never
 
     .. change::
         :tags: engine
-        :tickets: 
+        :tickets:
 
       StatementException wrapping will display the
       original exception class in the message.
 
     .. change::
         :tags: mssql
-        :tickets: 
+        :tickets:
 
       Adjusted the pyodbc dialect such that bound
       values are passed as bytes and not unicode
         :tickets: 2220
 
       repaired the oracle.RAW type which did not
-      generate the correct DDL. 
+      generate the correct DDL.
       Also in 0.6.9.
 
     .. change::
 
     .. change::
         :tags: oracle
-        :tickets: 
+        :tickets:
 
       Fixed bug in the mutable extension whereby
       if the same type were used twice in one
 
     .. change::
         :tags: oracle
-        :tickets: 
+        :tickets:
 
       Fixed bug in the mutable extension whereby
       if None or a non-corresponding type were set,
 
     .. change::
         :tags: examples
-        :tickets: 
+        :tickets:
 
       Repaired the examples/versioning test runner
       to not rely upon SQLAlchemy test libs,
 
     .. change::
         :tags: examples
-        :tickets: 
+        :tickets:
 
       Tweak to examples/versioning to pick the
       correct foreign key in a multi-level
 
     .. change::
         :tags: examples
-        :tickets: 
+        :tickets:
 
       Fixed the attribute shard example to check
       for bind param callable correctly in 0.7
 
     .. change::
         :tags: sql
-        :tickets: 
+        :tickets:
 
       Fixed bug whereby metadata.reflect(bind)
       would close a Connection passed as a
 
     .. change::
         :tags: sql
-        :tickets: 
+        :tickets:
 
       Streamlined the process by which a Select
       determines what's in it's '.c' collection.
 
     .. change::
         :tags: engine
-        :tickets: 
+        :tickets:
 
       Deprecate schema/SQL-oriented methods on
       Connection/Engine that were never well known
 
     .. change::
         :tags: mysql
-        :tickets: 
+        :tickets:
 
       Unit tests pass 100% on MySQL installed
       on windows.
 
     .. change::
         :tags: mysql
-        :tickets: 
+        :tickets:
 
       supports_sane_rowcount will be set to False
       if using MySQLdb and the DBAPI doesn't provide
     :released: Fri May 20 2011
 
     .. change::
-        :tags: 
-        :tickets: 
+        :tags:
+        :tickets:
 
       This section documents those changes from 0.7b4
       to 0.7.0.  For an overview of what's new in
       for joined-inh subclass related to itself,
       or joined-inh subclass related to a subclass
       of that with no cols in the sub-sub class
-      in the join condition. 
+      in the join condition.
       Also in 0.6.8.
 
     .. change::
 
     .. change::
         :tags: orm
-        :tickets: 
+        :tickets:
 
       added Query.with_session() method, switches
       Query to use a different session.
 
     .. change::
         :tags: orm
-        :tickets: 
+        :tickets:
 
       polymorphic_union() renders the columns in their
       original table order, as according to the first
 
       Fixed bug whereby mapper mapped to an anonymous
       alias would fail if logging were used, due to
-      unescaped % sign in the alias name. 
+      unescaped % sign in the alias name.
       Also in 0.6.8.
 
     .. change::
 
     .. change::
         :tags: sql
-        :tickets: 
+        :tickets:
 
       Changed the handling in determination of join
       conditions such that foreign key errors are
 
     .. change::
         :tags: sql
-        :tickets: 
+        :tickets:
 
       Some improvements to error handling inside
       of the execute procedure to ensure auto-close
 
     .. change::
         :tags: sql
-        :tickets: 
+        :tickets:
 
       metadata.reflect() and reflection.Inspector()
       had some reliance on GC to close connections
 
     .. change::
         :tags: postgresql
-        :tickets: 
+        :tickets:
 
       Fixed the psycopg2_version parsing in the
       psycopg2 dialect.
 
     .. change::
         :tags: examples
-        :tickets: 
+        :tickets:
 
       removed the ancient "polymorphic association"
       examples and replaced with an updated set of
 
     .. change::
         :tags: general
-        :tickets: 
+        :tickets:
 
       Changes to the format of CHANGES, this file.
       The format changes have been applied to
 
     .. change::
         :tags: general
-        :tickets: 
+        :tickets:
 
       The "-declarative" changes will now be listed
       directly under the "-orm" section, as these
 
     .. change::
         :tags: general
-        :tickets: 
+        :tickets:
 
       The 0.5 series changes have been moved to
       the file CHANGES_PRE_06 which replaces
 
     .. change::
         :tags: general
-        :tickets: 
+        :tickets:
 
       The changelog for 0.6.7 and subsequent within
       the 0.6 series is now listed only in the
 
     .. change::
         :tags: orm
-        :tickets: 
+        :tickets:
 
       Still more wording adjustments when a query option
       can't find the target entity.  Explain that the
       the back-referenced collection wouldn't
       properly handle add/removes with no net
       change.  Thanks to Richard Murri for the
-      test case + patch. 
+      test case + patch.
       (also in 0.6.7).
 
     .. change::
 
     .. change::
         :tags: sql
-        :tickets: 
+        :tickets:
 
       Restored the "catchall" constructor on the base
       TypeEngine class, with a deprecation warning.
 
       The limit/offset keywords to select() as well
       as the value passed to select.limit()/offset()
-      will be coerced to integer. 
+      will be coerced to integer.
       (also in 0.6.7)
 
     .. change::
         :tags: sql
-        :tickets: 
+        :tickets:
 
       fixed bug where "from" clause gathering from an
       over() clause would be an itertools.chain() and
 
     .. change::
         :tags: pool
-        :tickets: 
+        :tickets:
 
       The "pool.manage" feature doesn't use pickle
       anymore to hash the arguments for each pool.
 
       Fixed bug where reflection of foreign key
       created as "REFERENCES <tablename>" without
-      col name would fail. 
+      col name would fail.
       (also in 0.6.7)
 
     .. change::
         :tags: postgresql
-        :tickets: 
+        :tickets:
 
       Psycopg2 for Python 3 is now supported.
 
 
     .. change::
         :tags: general
-        :tickets: 
+        :tickets:
 
       Lots of fixes to unit tests when run under Pypy
       (courtesy Alex Gaynor).
 
       Changed the underlying approach to query.count().
       query.count() is now in all cases exactly:
-      
+
           query.
               from_self(func.count(literal_column('1'))).
               scalar()
-      
+
       That is, "select count(1) from (<full query>)".
       This produces a subquery in all cases, but
       vastly simplifies all the guessing count()
 
     .. change::
         :tags: sql
-        :tickets: 
+        :tickets:
 
       Added a fully descriptive error message for the
       case where Column is subclassed and _make_proxy()
 
     .. change::
         :tags: sql
-        :tickets: 
+        :tickets:
 
       To help with the "column_reflect" event being used
       with specific Table objects instead of all instances
         :tickets: 2073
 
       Fixed the BIT type to allow a "length" parameter, "varying"
-      parameter.  Reflection also fixed. 
+      parameter.  Reflection also fixed.
       (also in 0.6.7)
 
     .. change::
       typically when using the Inspector interface, to
       use sys.sql_modules instead of the information schema,
       thereby allowing views definitions longer than 4000
-      characters to be fully returned. 
+      characters to be fully returned.
       (also in 0.6.7)
 
     .. change::
 
     .. change::
         :tags: examples
-        :tickets: 
+        :tickets:
 
       Updated the association, association proxy examples
       to use declarative, added a new example
         :tickets: 2090
 
       The Beaker caching example allows a "query_cls" argument
-      to the query_callable() function. 
+      to the query_callable() function.
       (also in 0.6.7)
 
 .. changelog::
 
     .. change::
         :tags: examples
-        :tickets: 
+        :tickets:
 
       Beaker example now takes into account 'limit'
       and 'offset', bind params within embedded
     :released: Sat Feb 12 2011
 
     .. change::
-        :tags: 
-        :tickets: 
+        :tags:
+        :tickets:
 
       Detailed descriptions of each change below are
       described at:
 
     .. change::
         :tags: general
-        :tickets: 
+        :tickets:
 
       The "sqlalchemy.exceptions" alias in sys.modules
       has been removed.   Base SQLA exceptions are
 
     .. change::
         :tags: orm
-        :tickets: 
+        :tickets:
 
       Mutation Event Extension, supercedes "mutable=True"
 
 
     .. change::
         :tags: orm
-        :tickets: 
+        :tickets:
 
       Query.join(), Query.outerjoin(), eagerload(),
       eagerload_all(), others no longer allow lists
 
     .. change::
         :tags: orm
-        :tickets: 
+        :tickets:
 
       ScopedSession.mapper is removed (deprecated since 0.5).
 
 
     .. change::
         :tags: orm
-        :tickets: 
+        :tickets:
 
       The "name" field used in orm.aliased() now renders
       in the resulting SQL statement.
 
     .. change::
         :tags: orm
-        :tickets: 
+        :tickets:
 
       the value of "passive" as passed to
       attributes.get_history() should be one of the
 
       A warning is emitted when a joined-table inheriting mapper
       has no primary keys on the locally mapped table
-      (but has pks on the superclass table). 
+      (but has pks on the superclass table).
       (also in 0.6.7)
 
     .. change::
 
     .. change::
         :tags: sql
-        :tickets: 
+        :tickets:
 
       select.prefix_with() accepts multiple expressions
       (i.e. *expr), 'prefix' keyword argument to select()
 
     .. change::
         :tags: sql
-        :tickets: 
+        :tickets:
 
       Passing a string to the `distinct` keyword argument
       of `select()` for the purpose of emitting special
 
     .. change::
         :tags: sql
-        :tickets: 
+        :tickets:
 
       The Index() construct can be created inline with a Table
       definition, using strings as column names, as an alternative
 
     .. change::
         :tags: sql
-        :tickets: 
+        :tickets:
 
       Bind parameters present in the "columns clause" of a select
       are now auto-labeled like other "anonymous" clauses,
 
     .. change::
         :tags: sql
-        :tickets: 
+        :tickets:
 
       TypeDecorator is present in the "sqlalchemy" import space.
 
       specified, so that the default length, normally '1'
       as per SQL server documentation, is instead
       'unbounded'.  This also occurs for the VARBINARY type..
-      
+
       This behavior makes these types more closely compatible
       with Postgresql's VARCHAR type which is similarly unbounded
       when no length is specified.
         :tickets: 2047
 
       oursql dialect accepts the same "ssl" arguments in
-      create_engine() as that of MySQLdb. 
+      create_engine() as that of MySQLdb.
       (also in 0.6.7)
 
     .. change::

File doc/build/changelog/changelog_08.rst

     :version: 0.8.0b2
 
     .. change::
+        :tags: oracle, bug
+        :tickets: 2620
+
+      The Oracle LONG type, while an unbounded text type, does not appear
+      to use the cx_Oracle.LOB type when result rows are returned,
+      so the dialect has been repaired to exclude LONG from
+      having cx_Oracle.LOB filtering applied.  Also in 0.7.10.
+
+    .. change::
+        :tags: oracle, bug
+        :tickets: 2611
+
+      Repaired the usage of ``.prepare()`` in conjunction with
+      cx_Oracle so that a return value of ``False`` will result
+      in no call to ``connection.commit()``, hence avoiding
+      "no transaction" errors.   Two-phase transactions have
+      now been shown to work in a rudimental fashion with
+      SQLAlchemy and cx_oracle, however are subject to caveats
+      observed with the driver; check the documentation
+      for details.  Also in 0.7.10.
+
+    .. change::
+        :tags: sql, bug
+        :tickets: 2618
+
+      The :class:`.DECIMAL` type now honors the "precision" and
+      "scale" arguments when rendering DDL.
+
+    .. change::
+        :tags: orm, bug
+        :tickets: 2624
+
+      The :class:`.MutableComposite` type did not allow for the
+      :meth:`.MutableBase.coerce` method to be used, even though
+      the code seemed to indicate this intent, so this now works
+      and a brief example is added.  As a side-effect,
+      the mechanics of this event handler have been changed so that
+      new :class:`.MutableComposite` types no longer add per-type
+      global event handlers.  Also in 0.7.10.
+
+    .. change::
+        :tags: sql, bug
+        :tickets: 2621
+
+      Made an adjustment to the "boolean", (i.e. ``__nonzero__``)
+      evaluation of binary expressions, i.e. ``x1 == x2``, such
+      that the "auto-grouping" applied by :class:`.BinaryExpression`
+      in some cases won't get in the way of this comparison.
+      Previously, an expression like::
+
+        expr1 = mycolumn > 2
+        bool(expr1 == expr1)
+
+      Would evaulate as ``False``, even though this is an identity
+      comparison, because ``mycolumn > 2`` would be "grouped" before
+      being placed into the :class:`.BinaryExpression`, thus changing
+      its identity.   :class:`.BinaryExpression` now keeps track
+      of the "original" objects passed in.
+      Additionally the ``__nonzero__`` method now only returns if
+      the operator is ``==`` or ``!=`` - all others raise ``TypeError``.
+
+    .. change::
         :tags: firebird, bug
-        :ticket: 2622
+        :tickets: 2622
 
       Added missing import for "fdb" to the experimental
       "firebird+fdb" dialect.
 
     .. change::
         :tags: orm, bug
-        :ticket: 2614
+        :tickets: 2614
 
-      Added a new exception to detect the case where two
-      subclasses are being loaded using with_polymorphic(),
-      each subclass contains a relationship attribute of the same
-      name, and eager loading is being applied to one or both.
-      This is an ongoing bug which can't be immediately fixed,
-      so since the results are usually wrong in any case it raises an
-      exception for now.   0.7 has the same issue, so an exception
-      raise here probably means the code was returning the wrong
-      data in 0.7.
+      A second overhaul of aliasing/internal pathing mechanics
+      now allows two subclasses to have different relationships
+      of the same name, supported with subquery or joined eager
+      loading on both simultaneously when a full polymorphic
+      load is used.
+
+    .. change::
+        :tags: orm, bug
+        :tickets: 2617
+
+      Fixed bug whereby a multi-hop subqueryload within
+      a particular with_polymorphic load would produce a KeyError.
+      Takes advantage of the same internal pathing overhaul
+      as :ticket:`2614`.
 
     .. change::
         :tags: sql, bug

File doc/build/core/connections.rst

 requirement.
 
 The engine can be used directly to issue SQL to the database. The most generic
-way is first procure a connection resource, which you get via the :class:`connect` method::
+way is first procure a connection resource, which you get via the
+:meth:`.Engine.connect` method::
 
     connection = engine.connect()
     result = connection.execute("select username from users")
   on behalf of a particular mapped class, though the :class:`.Session`
   also features its own explicit system of establishing complex :class:`.Engine`/
   mapped class configurations.
-* The :meth:`.MetaData.create_all`, :meth:`.Metadata.drop_all`, :meth:`.Table.create`,
+* The :meth:`.MetaData.create_all`, :meth:`.MetaData.drop_all`, :meth:`.Table.create`,
   :meth:`.Table.drop`, and "autoload" features all make usage of the bound
   :class:`.Engine` automatically without the need to pass it explicitly.
 
         db.rollback()
 
 Explicit execution can be mixed with connectionless execution by
-using the :class:`.Engine.connect` method to acquire a :class:`.Connection`
+using the :meth:`.Engine.connect` method to acquire a :class:`.Connection`
 that is not part of the threadlocal scope::
 
     db.begin()

File doc/build/core/schema.rst

     ALTER TABLE users DROP CONSTRAINT cst_user_name_length
     DROP TABLE users{stop}
 
-The real usefulness of the above becomes clearer once we illustrate the :meth:`.DDLEvent.execute_if`
-method.  This method returns a modified form of the DDL callable which will
-filter on criteria before responding to a received event.   It accepts a
-parameter ``dialect``, which is the string name of a dialect or a tuple of such,
-which will limit the execution of the item to just those dialects.  It also
-accepts a ``callable_`` parameter which may reference a Python callable which will
-be invoked upon event reception, returning ``True`` or ``False`` indicating if
-the event should proceed.
+The real usefulness of the above becomes clearer once we illustrate the
+:meth:`.DDLElement.execute_if` method.  This method returns a modified form of
+the DDL callable which will filter on criteria before responding to a
+received event.   It accepts a parameter ``dialect``, which is the string
+name of a dialect or a tuple of such, which will limit the execution of the
+item to just those dialects.  It also accepts a ``callable_`` parameter which
+may reference a Python callable which will be invoked upon event reception,
+returning ``True`` or ``False`` indicating if the event should proceed.
 
 If our :class:`~sqlalchemy.schema.CheckConstraint` was only supported by
 Postgresql and not other databases, we could limit its usage to just that dialect::

File doc/build/orm/examples.rst

 Examples
 ========
 
-The SQLAlchemy distribution includes a variety of code examples illustrating a select set of patterns, some typical and some not so typical.   All are runnable and can be found in the ``/examples`` directory of the distribution.   Each example contains a README in its ``__init__.py`` file, each of which are listed below.
+The SQLAlchemy distribution includes a variety of code examples illustrating
+a select set of patterns, some typical and some not so typical.   All are
+runnable and can be found in the ``/examples`` directory of the
+distribution.   Each example contains a README in its ``__init__.py`` file,
+each of which are listed below.
 
-Additional SQLAlchemy examples, some user contributed, are available on the wiki at `<http://www.sqlalchemy.org/trac/wiki/UsageRecipes>`_.
+Additional SQLAlchemy examples, some user contributed, are available on the
+wiki at `<http://www.sqlalchemy.org/trac/wiki/UsageRecipes>`_.
 
 .. _examples_adjacencylist:
 

File doc/build/orm/extensions/mutable.rst

 -------------
 
 .. autoclass:: MutableBase
-    :members: _parents
+    :members: _parents, coerce
 
 .. autoclass:: Mutable
     :show-inheritance:

File examples/custom_attributes/__init__.py

 """
-Two examples illustrating modifications to SQLAlchemy's attribute management system.
+Two examples illustrating modifications to SQLAlchemy's attribute management
+system.
 
-``listen_for_events.py`` illustrates the usage of :class:`~sqlalchemy.orm.interfaces.AttributeExtension` to intercept attribute events.  It additionally illustrates a way to automatically attach these listeners to all class attributes using a :class:`~sqlalchemy.orm.interfaces.InstrumentationManager`.
+``listen_for_events.py`` illustrates the usage of
+:class:`~sqlalchemy.orm.interfaces.AttributeExtension` to intercept attribute
+events.  It additionally illustrates a way to automatically attach these
+listeners to all class attributes using a
+:class:`.InstrumentationManager`.
 
-``custom_management.py`` illustrates much deeper usage of :class:`~sqlalchemy.orm.interfaces.InstrumentationManager` as well as collection adaptation, to completely change the underlying method used to store state on an object.   This example was developed to illustrate techniques which would be used by other third party object instrumentation systems to interact with SQLAlchemy's event system and is only intended for very intricate framework integrations.
+``custom_management.py`` illustrates much deeper usage of
+:class:`.InstrumentationManager` as well as
+collection adaptation, to completely change the underlying method used to
+store state on an object.   This example was developed to illustrate
+techniques which would be used by other third party object instrumentation
+systems to interact with SQLAlchemy's event system and is only intended for
+very intricate framework integrations.
 
 """

File lib/sqlalchemy/dialects/oracle/cx_oracle.py

 Two Phase Transaction Support
 -----------------------------
 
-Two Phase transactions are implemented using XA transactions.  Success has been reported
-with this feature but it should be regarded as experimental.
+Two Phase transactions are implemented using XA transactions, and are known
+to work in a rudimental fashion with recent versions of cx_Oracle
+as of SQLAlchemy 0.8.0b2, 0.7.10.   However, the mechanism is not yet
+considered to be robust and should still be regarded as experimental.
+
+In particular, the cx_Oracle DBAPI as recently as 5.1.2 has a bug regarding
+two phase which prevents
+a particular DBAPI connection from being consistently usable in both
+prepared transactions as well as traditional DBAPI usage patterns; therefore
+once a particular connection is used via :meth:`.Connection.begin_prepared`,
+all subsequent usages of the underlying DBAPI connection must be within
+the context of prepared transactions.
+
+The default behavior of :class:`.Engine` is to maintain a pool of DBAPI
+connections.  Therefore, due to the above glitch, a DBAPI connection that has
+been used in a two-phase operation, and is then returned to the pool, will
+not be usable in a non-two-phase context.   To avoid this situation,
+the application can make one of several choices:
+
+* Disable connection pooling using :class:`.NullPool`
+
+* Ensure that the particular :class:`.Engine` in use is only used
+  for two-phase operations.   A :class:`.Engine` bound to an ORM
+  :class:`.Session` which includes ``twophase=True`` will consistently
+  use the two-phase transaction style.
+
+* For ad-hoc two-phase operations without disabling pooling, the DBAPI
+  connection in use can be evicted from the connection pool using the
+  :class:`.Connection.detach` method.
+
+.. versionchanged:: 0.8.0b2,0.7.10
+    Support for cx_oracle prepared transactions has been implemented
+    and tested.
+
 
 Precision Numerics
 ------------------
 
 """
 
-from .base import OracleCompiler, OracleDialect, \
-                                        RESERVED_WORDS, OracleExecutionContext
+from __future__ import absolute_import
+
+from .base import OracleCompiler, OracleDialect, OracleExecutionContext
 from . import base as oracle
 from ...engine import result as _result
 from sqlalchemy import types as sqltypes, util, exc, processors
         return dbapi.CLOB
 
 
+class _OracleLong(oracle.LONG):
+    # a raw LONG is a text type, but does *not*
+    # get the LobMixin with cx_oracle.
+
+    def get_dbapi_type(self, dbapi):
+        return dbapi.LONG_STRING
+
 class _OracleString(_NativeUnicodeMixin, sqltypes.String):
     pass
 
         sqltypes.UnicodeText: _OracleUnicodeText,
         sqltypes.CHAR: _OracleChar,
 
+        # a raw LONG is a text type, but does *not*
+        # get the LobMixin with cx_oracle.
+        oracle.LONG: _OracleLong,
+
         # this is only needed for OUT parameters.
         # it would be nice if we could not use it otherwise.
         sqltypes.Integer: _OracleInteger,
         connection.connection.begin(*xid)
 
     def do_prepare_twophase(self, connection, xid):
-        connection.connection.prepare()
+        result = connection.connection.prepare()
+        connection.info['cx_oracle_prepared'] = result
 
-    def do_rollback_twophase(self, connection, xid, is_prepared=True, recover=False):
+    def do_rollback_twophase(self, connection, xid, is_prepared=True,
+                                                recover=False):
         self.do_rollback(connection.connection)
 
-    def do_commit_twophase(self, connection, xid, is_prepared=True, recover=False):
-        self.do_commit(connection.connection)
+    def do_commit_twophase(self, connection, xid, is_prepared=True,
+                                                recover=False):
+        if not is_prepared:
+            self.do_commit(connection.connection)
+        else:
+            oci_prepared = connection.info['cx_oracle_prepared']
+            if oci_prepared:
+                self.do_commit(connection.connection)
 
     def do_recover_twophase(self, connection):
-        pass
+        connection.info.pop('cx_oracle_prepared', None)
 
 dialect = OracleDialect_cx_oracle

File lib/sqlalchemy/engine/base.py

 
         Note that any key/value can be passed to
         :meth:`.Connection.execution_options`, and it will be stored in the
-        ``_execution_options`` dictionary of the :class:`.Connnection`.   It
+        ``_execution_options`` dictionary of the :class:`.Connection`.   It
         is suitable for usage by end-user schemes to communicate with
         event listeners, for example.
 
 class Engine(Connectable, log.Identified):
     """
     Connects a :class:`~sqlalchemy.pool.Pool` and
-    :class:`~sqlalchemy.engine.base.Dialect` together to provide a source
-    of database connectivity and behavior.
+    :class:`~sqlalchemy.engine.interfaces.Dialect` together to provide a
+    source of database connectivity and behavior.
 
     An :class:`.Engine` object is instantiated publicly using the
     :func:`~sqlalchemy.create_engine` function.
 
     @property
     def name(self):
-        """String name of the :class:`~sqlalchemy.engine.Dialect` in use by
-        this ``Engine``."""
+        """String name of the :class:`~sqlalchemy.engine.interfaces.Dialect`
+        in use by this :class:`Engine`."""
 
         return self.dialect.name
 
     @property
     def driver(self):
-        """Driver name of the :class:`~sqlalchemy.engine.Dialect` in use by
-        this ``Engine``."""
+        """Driver name of the :class:`~sqlalchemy.engine.interfaces.Dialect`
+        in use by this :class:`Engine`."""
 
         return self.dialect.driver
 

File lib/sqlalchemy/engine/reflection.py

     """Performs database schema inspection.
 
     The Inspector acts as a proxy to the reflection methods of the
-    :class:`~sqlalchemy.engine.base.Dialect`, providing a
+    :class:`~sqlalchemy.engine.interfaces.Dialect`, providing a
     consistent interface as well as caching support for previously
     fetched metadata.
 
         engine = create_engine('...')
         insp = Inspector.from_engine(engine)
 
-    Where above, the :class:`~sqlalchemy.engine.base.Dialect` may opt
+    Where above, the :class:`~sqlalchemy.engine.interfaces.Dialect` may opt
     to return an :class:`.Inspector` subclass that provides additional
     methods specific to the dialect's target database.
 
     def __init__(self, bind):
         """Initialize a new :class:`.Inspector`.
 
-        :param bind: a :class:`~sqlalchemy.engine.base.Connectable`,
+        :param bind: a :class:`~sqlalchemy.engine.Connectable`,
           which is typically an instance of
           :class:`~sqlalchemy.engine.Engine` or
           :class:`~sqlalchemy.engine.Connection`.
 
         For a dialect-specific instance of :class:`.Inspector`, see
-        :meth:`Inspector.from_engine`
+        :meth:`.Inspector.from_engine`
 
         """
         # this might not be a connection, it could be an engine.
         """Construct a new dialect-specific Inspector object from the given
         engine or connection.
 
-        :param bind: a :class:`~sqlalchemy.engine.base.Connectable`,
+        :param bind: a :class:`~sqlalchemy.engine.Connectable`,
           which is typically an instance of
           :class:`~sqlalchemy.engine.Engine` or
           :class:`~sqlalchemy.engine.Connection`.
 
         This method differs from direct a direct constructor call of
         :class:`.Inspector` in that the
-        :class:`~sqlalchemy.engine.base.Dialect` is given a chance to provide
-        a dialect-specific :class:`.Inspector` instance, which may provide
-        additional methods.
+        :class:`~sqlalchemy.engine.interfaces.Dialect` is given a chance to
+        provide a dialect-specific :class:`.Inspector` instance, which may
+        provide additional methods.
 
         See the example at :class:`.Inspector`.
 

File lib/sqlalchemy/engine/result.py

         supports "returning" and the insert statement executed
         with the "implicit returning" enabled.
 
-        Raises :class:`.InvalidRequestError` if the executed
+        Raises :class:`~sqlalchemy.exc.InvalidRequestError` if the executed
         statement is not a compiled expression construct
         or is not an insert() construct.
 
         """Return the collection of updated parameters from this
         execution.
 
-        Raises :class:`.InvalidRequestError` if the executed
+        Raises :class:`~sqlalchemy.exc.InvalidRequestError` if the executed
         statement is not a compiled expression construct
         or is not an update() construct.
 
         """Return the collection of inserted parameters from this
         execution.
 
-        Raises :class:`.InvalidRequestError` if the executed
+        Raises :class:`~sqlalchemy.exc.InvalidRequestError` if the executed
         statement is not a compiled expression construct
         or is not an insert() construct.
 
 
         See :class:`.ExecutionContext` for details.
 
-        Raises :class:`.InvalidRequestError` if the executed
+        Raises :class:`~sqlalchemy.exc.InvalidRequestError` if the executed
         statement is not a compiled expression construct
         or is not an insert() or update() construct.
 
 
         See :class:`.ExecutionContext` for details.
 
-        Raises :class:`.InvalidRequestError` if the executed
+        Raises :class:`~sqlalchemy.exc.InvalidRequestError` if the executed
         statement is not a compiled expression construct
         or is not an insert() or update() construct.
 

File lib/sqlalchemy/event.py

         self._clslevel = util.defaultdict(list)
         self._empty_listeners = {}
 
+    def _contains(self, cls, evt):
+        return evt in self._clslevel[cls]
+
     def insert(self, obj, target, propagate):
         assert isinstance(target, type), \
                 "Class-level Event targets must be classes."

File lib/sqlalchemy/ext/compiler.py

 Compiling sub-elements of a custom expression construct
 =======================================================
 
-The ``compiler`` argument is the :class:`~sqlalchemy.engine.base.Compiled`
-object in use. This object can be inspected for any information about the
-in-progress compilation, including ``compiler.dialect``,
-``compiler.statement`` etc. The :class:`~sqlalchemy.sql.compiler.SQLCompiler`
-and :class:`~sqlalchemy.sql.compiler.DDLCompiler` both include a ``process()``
+The ``compiler`` argument is the
+:class:`~sqlalchemy.engine.interfaces.Compiled` object in use. This object
+can be inspected for any information about the in-progress compilation,
+including ``compiler.dialect``, ``compiler.statement`` etc. The
+:class:`~sqlalchemy.sql.compiler.SQLCompiler` and
+:class:`~sqlalchemy.sql.compiler.DDLCompiler` both include a ``process()``
 method which can be used for compilation of embedded attributes::
 
     from sqlalchemy.sql.expression import Executable, ClauseElement

File lib/sqlalchemy/ext/mutable.py

     >>> assert v1 in sess.dirty
     True
 
+Coercing Mutable Composites
+---------------------------
+
+The :meth:`.MutableBase.coerce` method is also supported on composite types.
+In the case of :class:`.MutableComposite`, the :meth:`.MutableBase.coerce`
+method is only called for attribute set operations, not load operations.
+Overriding the :meth:`.MutableBase.coerce` method is essentially equivalent
+to using a :func:`.validates` validation routine for all attributes which
+make use of the custom composite type::
+
+    class Point(MutableComposite):
+        # other Point methods
+        # ...
+
+        def coerce(cls, key, value):
+            if isinstance(value, tuple):
+                value = Point(*value)
+            elif not isinstance(value, Point):
+                raise ValueError("tuple or Point expected")
+            return value
+
+.. versionadded:: 0.7.10,0.8.0b2
+    Support for the :meth:`.MutableBase.coerce` method in conjunction with
+    objects of type :class:`.MutableComposite`.
+
 Supporting Pickling
 --------------------
 
 """
 from ..orm.attributes import flag_modified
 from .. import event, types
-from ..orm import mapper, object_mapper
+from ..orm import mapper, object_mapper, Mapper
 from ..util import memoized_property
 import weakref
 
 
     @classmethod
     def coerce(cls, key, value):
-        """Given a value, coerce it into this type.
+        """Given a value, coerce it into the target type.
 
-        By default raises ValueError.
+        Can be overridden by custom subclasses to coerce incoming
+        data into a particular type.
+
+        By default, raises ``ValueError``.
+
+        This method is called in different scenarios depending on if
+        the parent class is of type :class:`.Mutable` or of type
+        :class:`.MutableComposite`.  In the case of the former, it is called
+        for both attribute-set operations as well as during ORM loading
+        operations.  For the latter, it is only called during attribute-set
+        operations; the mechanics of the :func:`.composite` construct
+        handle coercion during load operations.
+
+
+        :param key: string name of the ORM-mapped attribute being set.
+        :param value: the incoming value.
+        :return: the method should return the coerced value, or raise
+         ``ValueError`` if the coercion cannot be completed.
+
         """
         if value is None:
             return None
         return sqltype
 
 
-class _MutableCompositeMeta(type):
-    def __init__(cls, classname, bases, dict_):
-        cls._setup_listeners()
-        return type.__init__(cls, classname, bases, dict_)
-
 
 class MutableComposite(MutableBase):
     """Mixin that defines transparent propagation of change
 
     See the example in :ref:`mutable_composites` for usage information.
 
-    .. warning::
-
-       The listeners established by the :class:`.MutableComposite`
-       class are *global* to all mappers, and are *not* garbage
-       collected.   Only use :class:`.MutableComposite` for types that are
-       permanent to an application, not with ad-hoc types else this will
-       cause unbounded growth in memory usage.
-
     """
-    __metaclass__ = _MutableCompositeMeta
 
     def changed(self):
         """Subclasses should call this method whenever change events occur."""
                                     prop._attribute_keys):
                 setattr(parent, attr_name, value)
 
-    @classmethod
-    def _setup_listeners(cls):
-        """Associate this wrapper with all future mapped composites
-        of the given type.
-
-        This is a convenience method that calls ``associate_with_attribute``
-        automatically.
-
-        """
-
-        def listen_for_type(mapper, class_):
-            for prop in mapper.iterate_properties:
-                if (hasattr(prop, 'composite_class') and
-                    issubclass(prop.composite_class, cls)):
-                    cls._listen_on_attribute(
-                        getattr(class_, prop.key), False, class_)
-
-        event.listen(mapper, 'mapper_configured', listen_for_type)
+def _setup_composite_listener():
+    def _listen_for_type(mapper, class_):
+        for prop in mapper.iterate_properties:
+            if (hasattr(prop, 'composite_class') and
+                issubclass(prop.composite_class, MutableComposite)):
+                prop.composite_class._listen_on_attribute(
+                    getattr(class_, prop.key), False, class_)
+    if not Mapper.dispatch.mapper_configured._contains(Mapper, _listen_for_type):
+        event.listen(Mapper, 'mapper_configured', _listen_for_type)
+_setup_composite_listener()
 
 
 class MutableDict(Mutable, dict):

File lib/sqlalchemy/ext/serializer.py

 from ..orm import class_mapper
 from ..orm.session import Session
 from ..orm.mapper import Mapper
+from ..orm.interfaces import MapperProperty
 from ..orm.attributes import QueryableAttribute
 from .. import Table, Column
 from ..engine import Engine
             id = "attribute:" + key + ":" + b64encode(pickle.dumps(cls))
         elif isinstance(obj, Mapper) and not obj.non_primary:
             id = "mapper:" + b64encode(pickle.dumps(obj.class_))
+        elif isinstance(obj, MapperProperty) and not obj.parent.non_primary:
+            id = "mapperprop:" + b64encode(pickle.dumps(obj.parent.class_)) + \
+                                    ":" + obj.key
         elif isinstance(obj, Table):
             id = "table:" + str(obj)
         elif isinstance(obj, Column) and isinstance(obj.table, Table):
             elif type_ == "mapper":
                 cls = pickle.loads(b64decode(args))
                 return class_mapper(cls)
+            elif type_ == "mapperprop":
+                mapper, keyname = args.split(':')
+                cls = pickle.loads(b64decode(args))
+                return class_mapper(cls).attrs[keyname]
             elif type_ == "table":
                 return metadata.tables[args]
             elif type_ == "column":

File lib/sqlalchemy/orm/deprecated_interfaces.py

        :class:`.SessionEvents`.
 
     Subclasses may be installed into a :class:`.Session` (or
-    :func:`.sessionmaker`) using the ``extension`` keyword
+    :class:`.sessionmaker`) using the ``extension`` keyword
     argument::
 
         from sqlalchemy.orm.interfaces import SessionExtension

File lib/sqlalchemy/orm/interfaces.py

 
         return operator(self.comparator, value)
 
+    def __repr__(self):
+        return '<%s at 0x%x; %s>' % (
+            self.__class__.__name__,
+            id(self), self.key)
 
 class PropComparator(operators.ColumnOperators):
     """Defines boolean, comparison, and other operators for
             return None
 
     def _get_context_strategy(self, context, path):
-        # this is essentially performance inlining.
-        key = ('loaderstrategy', path.reduced_path + (self.key,))
-        cls = None
-        if key in context.attributes:
-            cls = context.attributes[key]
-        else:
+        strategy_cls = path._inlined_get_for(self, context, 'loaderstrategy')
+
+        if not strategy_cls:
             wc_key = self._wildcard_path
             if wc_key and wc_key in context.attributes:
-                cls = context.attributes[wc_key]
+                strategy_cls = context.attributes[wc_key]
 
-        if cls:
+        if strategy_cls:
             try:
-                return self._strategies[cls]
+                return self._strategies[strategy_cls]
             except KeyError:
-                return self.__init_strategy(cls)
+                return self.__init_strategy(strategy_cls)
         return self.strategy
 
     def _get_strategy(self, cls):
     def _find_entity_prop_comparator(self, query, token, mapper, raiseerr):
         if orm_util._is_aliased_class(mapper):
             searchfor = mapper
-            isa = False
         else:
             searchfor = orm_util._class_to_mapper(mapper)
-            isa = True
         for ent in query._mapper_entities:
             if ent.corresponds_to(searchfor):
                 return ent
                 # exhaust current_path before
                 # matching tokens to entities
                 if current_path:
-                    if current_path[1] == token:
+                    if current_path[1].key == token:
                         current_path = current_path[2:]
                         continue
                     else:
                 # matching tokens to entities
                 if current_path:
                     if current_path[0:2] == \
-                            [token._parententity, prop.key]:
+                            [token._parententity, prop]:
                         current_path = current_path[2:]
                         continue
                     else:
                                             raiseerr)
                     if not entity:
                         return no_result
+
                     path_element = entity.entity_zero
                     mapper = entity.mapper
             else:
                 raise sa_exc.ArgumentError("Attribute '%s' does not "
                             "link from element '%s'" % (token, path_element))
 
-            path = path[path_element][prop.key]
+            path = path[path_element][prop]
 
             paths.append(path)
 
                 if not ext_info.is_aliased_class:
                     ac = orm_util.with_polymorphic(
                                 ext_info.mapper.base_mapper,
-                                ext_info.mapper, aliased=True)
+                                ext_info.mapper, aliased=True,
+                                _use_mapper_path=True)
                     ext_info = inspect(ac)
                 path.set(query, "path_with_polymorphic", ext_info)
             else:

File lib/sqlalchemy/orm/loading.py

     new_populators = []
     existing_populators = []
     eager_populators = []