]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
split CHANGES into CHANGES and CHANGES_PRE_05, since I would like CHANGES to be viewa...
authorMike Bayer <mike_mp@zzzcomputing.com>
Mon, 15 Jun 2009 22:11:08 +0000 (22:11 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Mon, 15 Jun 2009 22:11:08 +0000 (22:11 +0000)
CHANGES
CHANGES_PRE_05 [new file with mode: 0644]

diff --git a/CHANGES b/CHANGES
index 0259b1105d86257e24cd01d0c28714046c4117cc..638c5e356eecf10c8aab1652720b0ec026a77fc1 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1748,4104 +1748,5 @@ full changes between 0.4/0.5.
     - Added support for returning values from inserts (2.0+ only),
       updates and deletes (2.1+ only).
 
-0.4.7
-=====
-- orm
-    - The contains() operator when used with many-to-many
-      will alias() the secondary (association) table so
-      that multiple contains() calls will not conflict
-      with each other [ticket:1058]
-
-    - fixed bug preventing merge() from functioning in
-      conjunction with a comparable_property()
-
-    - the enable_typechecks=False setting on relation()
-      now only allows subtypes with inheriting mappers.
-      Totally unrelated types, or subtypes not set up with
-      mapper inheritance against the target mapper are
-      still not allowed.
-
-    - Added is_active flag to Sessions to detect when
-      a transaction is in progress [ticket:976].  This
-      flag is always True with a "transactional"
-      (in 0.5 a non-"autocommit") Session.
-
-- sql
-    - Fixed bug when calling select([literal('foo')])
-      or select([bindparam('foo')]).
-
-- schema
-    - create_all(), drop_all(), create(), drop() all raise
-      an error if the table name or schema name contains
-      more characters than that dialect's configured
-      character limit.  Some DB's can handle too-long
-      table names during usage, and SQLA can handle this
-      as well. But various reflection/
-      checkfirst-during-create scenarios fail since we are
-      looking for the name within the DB's catalog tables.
-      [ticket:571]
-
-    - The index name generated when you say "index=True"
-      on a Column is truncated to the length appropriate
-      for the dialect. Additionally, an Index with a too-
-      long name cannot be explicitly dropped with
-      Index.drop(), similar to [ticket:571].
-      [ticket:820]
-
-- postgres
-    - Repaired server_side_cursors to properly detect
-      text() clauses.
-
-    - Added PGCidr type. [ticket:1092]
-
-- mysql
-    - Added 'CALL' to the list of SQL keywords which return
-      result rows.
-
-- oracle
-    - Oracle get_default_schema_name() "normalizes" the name
-      before returning, meaning it returns a lower-case name
-      when the identifier is detected as case insensitive.
-
-    - creating/dropping tables takes schema name into account
-      when searching for the existing table, so that tables
-      in other owner namespaces with the same name do not
-      conflict [ticket:709]
-
-    - Cursors now have "arraysize" set to 50 by default on
-      them, the value of which is configurable using the
-      "arraysize" argument to create_engine() with the
-      Oracle dialect.  This to account for cx_oracle's default
-      setting of "1", which has the effect of many round trips
-      being sent to Oracle.  This actually works well in
-      conjunction with BLOB/CLOB-bound cursors, of which
-      there are any number available but only for the life of
-      that row request (so BufferedColumnRow is still needed,
-      but less so). [ticket:1062]
-
-- sqlite
-      - add SLFloat type, which matches the SQLite REAL
-        type affinity.  Previously, only SLNumeric was provided
-        which fulfills NUMERIC affinity, but that's not the
-        same as REAL.
-
-0.4.6
-=====
-- orm
-    - Fix to the recent relation() refactoring which fixes
-      exotic viewonly relations which join between local and
-      remote table multiple times, with a common column shared
-      between the joins.
-
-    - Also re-established viewonly relation() configurations
-      that join across multiple tables.
-
-    - Added experimental relation() flag to help with
-      primaryjoins across functions, etc.,
-      _local_remote_pairs=[tuples].  This complements a complex
-      primaryjoin condition allowing you to provide the
-      individual column pairs which comprise the relation's
-      local and remote sides.  Also improved lazy load SQL
-      generation to handle placing bind params inside of
-      functions and other expressions.  (partial progress
-      towards [ticket:610])
-
-    - repaired single table inheritance such that you
-      can single-table inherit from a joined-table inherting
-      mapper without issue [ticket:1036].
-
-    - Fixed "concatenate tuple" bug which could occur with
-      Query.order_by() if clause adaption had taken place.
-      [ticket:1027]
-
-    - Removed ancient assertion that mapped selectables require
-      "alias names" - the mapper creates its own alias now if
-      none is present.  Though in this case you need to use the
-      class, not the mapped selectable, as the source of column
-      attributes - so a warning is still issued.
-
-    - fixes to the "exists" function involving inheritance (any(),
-      has(), ~contains()); the full target join will be rendered
-      into the EXISTS clause for relations that link to subclasses.
-
-    - restored usage of append_result() extension method for primary
-      query rows, when the extension is present and only a single-
-      entity result is being returned.
-
-    - Also re-established viewonly relation() configurations that
-      join across multiple tables.
-
-    - removed ancient assertion that mapped selectables require
-      "alias names" - the mapper creates its own alias now if
-      none is present.  Though in this case you need to use
-      the class, not the mapped selectable, as the source of
-      column attributes - so a warning is still issued.
-
-    - refined mapper._save_obj() which was unnecessarily calling
-      __ne__() on scalar values during flush [ticket:1015]
-
-    - added a feature to eager loading whereby subqueries set
-      as column_property() with explicit label names (which is not
-      necessary, btw) will have the label anonymized when
-      the instance is part of the eager join, to prevent
-      conflicts with a subquery or column of the same name
-      on the parent object.  [ticket:1019]
-
-    - set-based collections |=, -=, ^= and &= are stricter about
-      their operands and only operate on sets, frozensets or
-      subclasses of the collection type. Previously, they would
-      accept any duck-typed set.
-
-    - added an example dynamic_dict/dynamic_dict.py, illustrating
-      a simple way to place dictionary behavior on top of
-      a dynamic_loader.
-
-- declarative extension
-    - Joined table inheritance mappers use a slightly relaxed
-      function to create the "inherit condition" to the parent
-      table, so that other foreign keys to not-yet-declared
-      Table objects don't trigger an error.
-
-    - fixed reentrant mapper compile hang when
-      a declared attribute is used within ForeignKey,
-      ie. ForeignKey(MyOtherClass.someattribute)
-
-- sql
-    - Added COLLATE support via the .collate(<collation>)
-      expression operator and collate(<expr>, <collation>) sql
-      function.
-
-    - Fixed bug with union() when applied to non-Table connected
-      select statements
-
-    - improved behavior of text() expressions when used as
-      FROM clauses, such as select().select_from(text("sometext"))
-      [ticket:1014]
-
-    - Column.copy() respects the value of "autoincrement",
-      fixes usage with Migrate [ticket:1021]
-
-- engines
-    - Pool listeners can now be provided as a dictionary of
-      callables or a (possibly partial) duck-type of
-      PoolListener, your choice.
-
-    - added "rollback_returned" option to Pool which will
-      disable the rollback() issued when connections are
-      returned.  This flag is only safe to use with a database
-      which does not support transactions (i.e. MySQL/MyISAM).
-
-- ext
-    - set-based association proxies |=, -=, ^= and &= are
-      stricter about their operands and only operate on sets,
-      frozensets or other association proxies. Previously, they
-      would accept any duck-typed set.
-
-- mssql
-    - Added "odbc_autotranslate" parameter to engine / dburi
-      parameters. Any given string will be passed through to the
-      ODBC connection string as:
-
-            "AutoTranslate=%s" % odbc_autotranslate
-
-      [ticket:1005]
-
-    - Added "odbc_options" parameter to engine / dburi
-      parameters. The given string is simply appended to the
-      SQLAlchemy-generated odbc connection string.
-
-      This should obviate the need of adding a myriad of ODBC
-      options in the future.
-
-- firebird
-    - Handle the "SUBSTRING(:string FROM :start FOR :length)"
-      builtin.
-
-0.4.5
-=====
-- orm
-    - A small change in behavior to session.merge() - existing
-      objects are checked for based on primary key attributes, not
-      necessarily _instance_key.  So the widely requested
-      capability, that:
-
-            x = MyObject(id=1)
-            x = sess.merge(x)
-
-      will in fact load MyObject with id #1 from the database if
-      present, is now available.  merge() still copies the state
-      of the given object to the persistent one, so an example
-      like the above would typically have copied "None" from all
-      attributes of "x" onto the persistent copy.  These can be
-      reverted using session.expire(x).
-
-    - Also fixed behavior in merge() whereby collection elements
-      present on the destination but not the merged collection
-      were not being removed from the destination.
-
-    - Added a more aggressive check for "uncompiled mappers",
-      helps particularly with declarative layer [ticket:995]
-
-    - The methodology behind "primaryjoin"/"secondaryjoin" has
-      been refactored.  Behavior should be slightly more
-      intelligent, primarily in terms of error messages which
-      have been pared down to be more readable.  In a slight
-      number of scenarios it can better resolve the correct
-      foreign key than before.
-
-    - Added comparable_property(), adds query Comparator
-      behavior to regular, unmanaged Python properties
-
-    - the functionality of query.with_polymorphic() has
-      been added to mapper() as a configuration option.
-
-      It's set via several forms:
-            with_polymorphic='*'
-            with_polymorphic=[mappers]
-            with_polymorphic=('*', selectable)
-            with_polymorphic=([mappers], selectable)
-
-      This controls the default polymorphic loading strategy
-      for inherited mappers. When a selectable is not given,
-      outer joins are created for all joined-table inheriting
-      mappers requested. Note that the auto-create of joins
-      is not compatible with concrete table inheritance.
-
-      The existing select_table flag on mapper() is now
-      deprecated and is synonymous with
-      with_polymorphic('*', select_table).  Note that the
-      underlying "guts" of select_table have been
-      completely removed and replaced with the newer,
-      more flexible approach.
-
-      The new approach also automatically allows eager loads
-      to work for subclasses, if they are present, for
-      example
-        sess.query(Company).options(
-         eagerload_all(
-          [Company.employees.of_type(Engineer), 'machines']
-        ))
-      to load Company objects, their employees, and the
-      'machines' collection of employees who happen to be
-      Engineers. A "with_polymorphic" Query option should be
-      introduced soon as well which would allow per-Query
-      control of with_polymorphic() on relations.
-
-    - added two "experimental" features to Query,
-      "experimental" in that their specific name/behavior
-      is not carved in stone just yet:  _values() and
-      _from_self().  We'd like feedback on these.
-
-      - _values(*columns) is given a list of column
-        expressions, and returns a new Query that only
-        returns those columns. When evaluated, the return
-        value is a list of tuples just like when using
-        add_column() or add_entity(), the only difference is
-        that "entity zero", i.e. the mapped class, is not
-        included in the results. This means it finally makes
-        sense to use group_by() and having() on Query, which
-        have been sitting around uselessly until now.
-
-        A future change to this method may include that its
-        ability to join, filter and allow other options not
-        related to a "resultset" are removed, so the feedback
-        we're looking for is how people want to use
-        _values()...i.e. at the very end, or do people prefer
-        to continue generating after it's called.
-
-      - _from_self() compiles the SELECT statement for the
-        Query (minus any eager loaders), and returns a new
-        Query that selects from that SELECT. So basically you
-        can query from a Query without needing to extract the
-        SELECT statement manually. This gives meaning to
-        operations like query[3:5]._from_self().filter(some
-        criterion). There's not much controversial here
-        except that you can quickly create highly nested
-        queries that are less efficient, and we want feedback
-        on the naming choice.
-
-    - query.order_by() and query.group_by() will accept
-      multiple arguments using *args (like select()
-      already does).
-
-    - Added some convenience descriptors to Query:
-      query.statement returns the full SELECT construct,
-      query.whereclause returns just the WHERE part of the
-      SELECT construct.
-
-    - Fixed/covered case when using a False/0 value as a
-      polymorphic discriminator.
-
-    - Fixed bug which was preventing synonym() attributes from
-      being used with inheritance
-
-    - Fixed SQL function truncation of trailing underscores
-      [ticket:996]
-
-    - When attributes are expired on a pending instance, an
-      error will not be raised when the "refresh" action is
-      triggered and no result is found.
-
-    - Session.execute can now find binds from metadata
-
-    - Adjusted the definition of "self-referential" to be any
-      two mappers with a common parent (this affects whether or
-      not aliased=True is required when joining with Query).
-
-    - Made some fixes to the "from_joinpoint" argument to
-      query.join() so that if the previous join was aliased and
-      this one isn't, the join still happens successfully.
-
-    - Assorted "cascade deletes" fixes:
-        - Fixed "cascade delete" operation of dynamic relations,
-          which had only been implemented for foreign-key
-          nulling behavior in 0.4.2 and not actual cascading
-          deletes [ticket:895]
-
-        - Delete cascade without delete-orphan cascade on a
-          many-to-one will not delete orphans which were
-          disconnected from the parent before session.delete()
-          is called on the parent (one-to-many already had
-          this).
-
-        - Delete cascade with delete-orphan will delete orphans
-          whether or not it remains attached to its also-deleted
-          parent.
-
-        - delete-orphan casacde is properly detected on relations
-          that are present on superclasses when using inheritance.
-
-    - Fixed order_by calculation in Query to properly alias
-      mapper-config'ed order_by when using select_from()
-
-    - Refactored the diffing logic that kicks in when replacing
-      one collection with another into collections.bulk_replace,
-      useful to anyone building multi-level collections.
-
-    - Cascade traversal algorithm converted from recursive to
-      iterative to support deep object graphs.
-
-- sql
-    - schema-qualified tables now will place the schemaname
-      ahead of the tablename in all column expressions as well
-      as when generating column labels.  This prevents cross-
-      schema name collisions in all cases [ticket:999]
-
-    - can now allow selects which correlate all FROM clauses
-      and have no FROM themselves.  These are typically
-      used in a scalar context, i.e. SELECT x, (SELECT x WHERE y)
-      FROM table.  Requires explicit correlate() call.
-
-    - 'name' is no longer a required constructor argument for
-      Column().  It (and .key) may now be deferred until the
-      column is added to a Table.
-
-    - like(), ilike(), contains(), startswith(), endswith() take
-      an optional keyword argument "escape=<somestring>", which
-      is set as the escape character using the syntax "x LIKE y
-      ESCAPE '<somestring>'" [ticket:993], [ticket:791]
-
-    - random() is now a generic sql function and will compile to
-      the database's random implementation, if any.
-
-    - update().values() and insert().values() take keyword
-      arguments.
-
-    - Fixed an issue in select() regarding its generation of
-      FROM clauses, in rare circumstances two clauses could be
-      produced when one was intended to cancel out the other.
-      Some ORM queries with lots of eager loads might have seen
-      this symptom.
-
-    - The case() function now also takes a dictionary as its
-      whens parameter.  It also interprets the "THEN"
-      expressions as values by default, meaning case([(x==y,
-      "foo")]) will interpret "foo" as a bound value, not a SQL
-      expression.  use text(expr) for literal SQL expressions in
-      this case.  For the criterion itself, these may be literal
-      strings only if the "value" keyword is present, otherwise
-      SA will force explicit usage of either text() or
-      literal().
-
-- oracle
-    - The "owner" keyword on Table is now deprecated, and is
-      exactly synonymous with the "schema" keyword.  Tables can
-      now be reflected with alternate "owner" attributes,
-      explicitly stated on the Table object or not using
-      "schema".
-
-    - All of the "magic" searching for synonyms, DBLINKs etc.
-      during table reflection are disabled by default unless you
-      specify "oracle_resolve_synonyms=True" on the Table
-      object.  Resolving synonyms necessarily leads to some
-      messy guessing which we'd rather leave off by default.
-      When the flag is set, tables and related tables will be
-      resolved against synonyms in all cases, meaning if a
-      synonym exists for a particular table, reflection will use
-      it when reflecting related tables.  This is stickier
-      behavior than before which is why it's off by default.
-
-- declarative extension
-    - The "synonym" function is now directly usable with
-      "declarative".  Pass in the decorated property using the
-      "descriptor" keyword argument, e.g.: somekey =
-      synonym('_somekey', descriptor=property(g, s))
-
-    - The "deferred" function is usable with "declarative".
-      Simplest usage is to declare deferred and Column together,
-      e.g.: data = deferred(Column(Text))
-
-    - Declarative also gained @synonym_for(...) and
-      @comparable_using(...), front-ends for synonym and
-      comparable_property.
-
-    - Improvements to mapper compilation when using declarative;
-      already-compiled mappers will still trigger compiles of
-      other uncompiled mappers when used [ticket:995]
-
-    - Declarative will complete setup for Columns lacking names,
-      allows a more DRY syntax.
-
-        class Foo(Base):
-            __tablename__ = 'foos'
-            id = Column(Integer, primary_key=True)
-
-     - inheritance in declarative can be disabled when sending
-       "inherits=None" to __mapper_args__.
-
-     - declarative_base() takes optional kwarg "mapper", which
-       is any callable/class/method that produces a mapper,
-       such as declarative_base(mapper=scopedsession.mapper).
-       This property can also be set on individual declarative
-       classes using the "__mapper_cls__" property.
-
-- postgres
-    - Got PG server side cursors back into shape, added fixed
-      unit tests as part of the default test suite.  Added
-      better uniqueness to the cursor ID [ticket:1001]
-
-- oracle
-    - The "owner" keyword on Table is now deprecated, and is
-      exactly synonymous with the "schema" keyword.  Tables can
-      now be reflected with alternate "owner" attributes,
-      explicitly stated on the Table object or not using
-      "schema".
-
-    - All of the "magic" searching for synonyms, DBLINKs etc.
-      during table reflection are disabled by default unless you
-      specify "oracle_resolve_synonyms=True" on the Table
-      object.  Resolving synonyms necessarily leads to some
-      messy guessing which we'd rather leave off by default.
-      When the flag is set, tables and related tables will be
-      resolved against synonyms in all cases, meaning if a
-      synonym exists for a particular table, reflection will use
-      it when reflecting related tables.  This is stickier
-      behavior than before which is why it's off by default.
-
-- mssql
-     - Reflected tables will now automatically load other tables
-       which are referenced by Foreign keys in the auto-loaded
-       table, [ticket:979].
-
-     - Added executemany check to skip identity fetch, [ticket:916].
-
-     - Added stubs for small date type, [ticket:884]
-
-     - Added a new 'driver' keyword parameter for the pyodbc dialect.
-       Will substitute into the ODBC connection string if given,
-       defaults to 'SQL Server'.
-
-     - Added a new 'max_identifier_length' keyword parameter for
-       the pyodbc dialect.
-
-     - Improvements to pyodbc + Unix. If you couldn't get that
-       combination to work before, please try again.
-
-- mysql
-     - The connection.info keys the dialect uses to cache server
-       settings have changed and are now namespaced.
-
-0.4.4
-------
-- sql
-    - Can again create aliases of selects against textual FROM
-      clauses, [ticket:975]
-
-    - The value of a bindparam() can be a callable, in which
-      case it's evaluated at statement execution time to get the
-      value.
-
-    - Added exception wrapping/reconnect support to result set
-      fetching.  Reconnect works for those databases that raise
-      a catchable data error during results (i.e. doesn't work
-      on MySQL) [ticket:978]
-
-    - Implemented two-phase API for "threadlocal" engine, via
-      engine.begin_twophase(), engine.prepare() [ticket:936]
-
-    - Fixed bug which was preventing UNIONS from being
-      cloneable, [ticket:986]
-
-    - Added "bind" keyword argument to insert(), update(),
-      delete() and DDL(). The .bind property is now assignable
-      on those statements as well as on select().
-
-    - Insert statements can now be compiled with extra "prefix"
-      words between INSERT and INTO, for vendor extensions like
-      MySQL's INSERT IGNORE INTO table.
-
-- orm
-    - any(), has(), contains(), ~contains(), attribute level ==
-      and != now work properly with self-referential relations -
-      the clause inside the EXISTS is aliased on the "remote"
-      side to distinguish it from the parent table.  This
-      applies to single table self-referential as well as
-      inheritance-based self-referential.
-
-    - Repaired behavior of == and != operators at the relation()
-      level when compared against NULL for one-to-one relations
-      [ticket:985]
-
-    - Fixed bug whereby session.expire() attributes were not
-      loading on an polymorphically-mapped instance mapped by a
-      select_table mapper.
-
-    - Added query.with_polymorphic() - specifies a list of
-      classes which descend from the base class, which will be
-      added to the FROM clause of the query.  Allows subclasses
-      to be used within filter() criterion as well as eagerly
-      loads the attributes of those subclasses.
-
-    - Your cries have been heard: removing a pending item from
-      an attribute or collection with delete-orphan expunges the
-      item from the session; no FlushError is raised.  Note that
-      if you session.save()'ed the pending item explicitly, the
-      attribute/collection removal still knocks it out.
-
-    - session.refresh() and session.expire() raise an error when
-      called on instances which are not persistent within the
-      session
-
-    - Fixed potential generative bug when the same Query was
-      used to generate multiple Query objects using join().
-
-    - Fixed bug which was introduced in 0.4.3, whereby loading
-      an already-persistent instance mapped with joined table
-      inheritance would trigger a useless "secondary" load from
-      its joined table, when using the default "select"
-      polymorphic_fetch.  This was due to attributes being
-      marked as expired during its first load and not getting
-      unmarked from the previous "secondary" load.  Attributes
-      are now unexpired based on presence in __dict__ after any
-      load or commit operation succeeds.
-
-    - Deprecated Query methods apply_sum(), apply_max(),
-      apply_min(), apply_avg().  Better methodologies are
-      coming....
-
-    - relation() can accept a callable for its first argument,
-      which returns the class to be related.  This is in place
-      to assist declarative packages to define relations without
-      classes yet being in place.
-
-    - Added a new "higher level" operator called "of_type()":
-      used in join() as well as with any() and has(), qualifies
-      the subclass which will be used in filter criterion, e.g.:
-
-        query.filter(Company.employees.of_type(Engineer).
-          any(Engineer.name=='foo'))
-
-        or
-
-        query.join(Company.employees.of_type(Engineer)).
-          filter(Engineer.name=='foo')
-
-    - Preventive code against a potential lost-reference bug in
-      flush().
-
-    - Expressions used in filter(), filter_by() and others, when
-      they make usage of a clause generated from a relation
-      using the identity of a child object (e.g.,
-      filter(Parent.child==<somechild>)), evaluate the actual
-      primary key value of <somechild> at execution time so that
-      the autoflush step of the Query can complete, thereby
-      populating the PK value of <somechild> in the case that
-      <somechild> was pending.
-
-    - setting the relation()-level order by to a column in the
-      many-to-many "secondary" table will now work with eager
-      loading, previously the "order by" wasn't aliased against
-      the secondary table's alias.
-
-    - Synonyms riding on top of existing descriptors are now
-      full proxies to those descriptors.
-
-- dialects
-    - Invalid SQLite connection URLs now raise an error.
-
-    - postgres TIMESTAMP renders correctly [ticket:981]
-
-    - postgres PGArray is a "mutable" type by default; when used
-      with the ORM, mutable-style equality/ copy-on-write
-      techniques are used to test for changes.
-
-- extensions
-    - a new super-small "declarative" extension has been added,
-      which allows Table and mapper() configuration to take
-      place inline underneath a class declaration.  This
-      extension differs from ActiveMapper and Elixir in that it
-      does not redefine any SQLAlchemy semantics at all; literal
-      Column, Table and relation() constructs are used to define
-      the class behavior and table definition.
-
-0.4.3
-------
-- sql
-    - Added "schema.DDL", an executable free-form DDL statement.
-      DDLs can be executed in isolation or attached to Table or
-      MetaData instances and executed automatically when those
-      objects are created and/or dropped.
-
-    - Table columns and constraints can be overridden on a an
-      existing table (such as a table that was already reflected)
-      using the 'useexisting=True' flag, which now takes into
-      account the arguments passed along with it.
-
-    - Added a callable-based DDL events interface, adds hooks
-      before and after Tables and MetaData create and drop.
-
-    - Added generative where(<criterion>) method to delete() and
-      update() constructs which return a new object with criterion
-      joined to existing criterion via AND, just like
-      select().where().
-
-    - Added "ilike()" operator to column operations.  Compiles to
-      ILIKE on postgres, lower(x) LIKE lower(y) on all
-      others. [ticket:727]
-
-    - Added "now()" as a generic function; on SQLite, Oracle
-      and MSSQL compiles as "CURRENT_TIMESTAMP"; "now()" on
-      all others. [ticket:943]
-
-    - The startswith(), endswith(), and contains() operators now
-      concatenate the wildcard operator with the given operand in
-      SQL, i.e. "'%' || <bindparam>" in all cases, accept
-      text('something') operands properly [ticket:962]
-
-    - cast() accepts text('something') and other non-literal
-      operands properly [ticket:962]
-
-    - fixed bug in result proxy where anonymously generated
-      column labels would not be accessible using their straight
-      string name
-
-    - Deferrable constraints can now be defined.
-
-    - Added "autocommit=True" keyword argument to select() and
-      text(), as well as generative autocommit() method on
-      select(); for statements which modify the database through
-      some user-defined means other than the usual INSERT/UPDATE/
-      DELETE etc.  This flag will enable "autocommit" behavior
-      during execution if no transaction is in progress.
-      [ticket:915]
-
-    - The '.c.' attribute on a selectable now gets an entry for
-      every column expression in its columns clause.  Previously,
-      "unnamed" columns like functions and CASE statements weren't
-      getting put there.  Now they will, using their full string
-      representation if no 'name' is available.
-
-    - a CompositeSelect, i.e. any union(), union_all(),
-      intersect(), etc. now asserts that each selectable contains
-      the same number of columns.  This conforms to the
-      corresponding SQL requirement.
-
-    - The anonymous 'label' generated for otherwise unlabeled
-      functions and expressions now propagates outwards at compile
-      time for expressions like select([select([func.foo()])]).
-
-    - Building on the above ideas, CompositeSelects now build up
-      their ".c." collection based on the names present in the
-      first selectable only; corresponding_column() now works
-      fully for all embedded selectables.
-
-    - Oracle and others properly encode SQL used for defaults like
-      sequences, etc., even if no unicode idents are used since
-      identifier preparer may return a cached unicode identifier.
-
-    - Column and clause comparisons to datetime objects on the
-      left hand side of the expression now work (d < table.c.col).
-      (datetimes on the RHS have always worked, the LHS exception
-      is a quirk of the datetime implementation.)
-
-- orm
-    - Every Session.begin() must now be accompanied by a
-      corresponding commit() or rollback() unless the session is
-      closed with Session.close().  This also includes the begin()
-      which is implicit to a session created with
-      transactional=True.  The biggest change introduced here is
-      that when a Session created with transactional=True raises
-      an exception during flush(), you must call
-      Session.rollback() or Session.close() in order for that
-      Session to continue after an exception.
-
-    - Fixed merge() collection-doubling bug when merging transient
-      entities with backref'ed collections.  [ticket:961]
-
-    - merge(dont_load=True) does not accept transient entities,
-      this is in continuation with the fact that
-      merge(dont_load=True) does not accept any "dirty" objects
-      either.
-
-    - Added standalone "query" class attribute generated by a
-      scoped_session.  This provides MyClass.query without using
-      Session.mapper.  Use via:
-
-        MyClass.query = Session.query_property()
-
-    - The proper error message is raised when trying to access
-      expired instance attributes with no session present
-
-    - dynamic_loader() / lazy="dynamic" now accepts and uses
-      the order_by parameter in the same way in which it works
-      with relation().
-
-    - Added expire_all() method to Session.  Calls expire() for
-      all persistent instances.  This is handy in conjunction
-      with...
-
-    - Instances which have been partially or fully expired will
-      have their expired attributes populated during a regular
-      Query operation which affects those objects, preventing a
-      needless second SQL statement for each instance.
-
-    - Dynamic relations, when referenced, create a strong
-      reference to the parent object so that the query still has a
-      parent to call against even if the parent is only created
-      (and otherwise dereferenced) within the scope of a single
-      expression. [ticket:938]
-
-    - Added a mapper() flag "eager_defaults". When set to True,
-      defaults that are generated during an INSERT or UPDATE
-      operation are post-fetched immediately, instead of being
-      deferred until later.  This mimics the old 0.3 behavior.
-
-    - query.join() can now accept class-mapped attributes as
-      arguments. These can be used in place or in any combination
-      with strings.  In particular this allows construction of
-      joins to subclasses on a polymorphic relation, i.e.:
-
-        query(Company).join(['employees', Engineer.name])
-
-    - query.join() can also accept tuples of attribute name/some
-      selectable as arguments.  This allows construction of joins
-      *from* subclasses of a polymorphic relation, i.e.:
-
-        query(Company).\
-        join(
-          [('employees', people.join(engineer)), Engineer.name]
-        )
-
-    - General improvements to the behavior of join() in
-      conjunction with polymorphic mappers, i.e. joining from/to
-      polymorphic mappers and properly applying aliases.
-
-    - Fixed/improved behavior when a mapper determines the natural
-      "primary key" of a mapped join, it will more effectively
-      reduce columns which are equivalent via foreign key
-      relation.  This affects how many arguments need to be sent
-      to query.get(), among other things.  [ticket:933]
-
-    - The lazy loader can now handle a join condition where the
-      "bound" column (i.e. the one that gets the parent id sent as
-      a bind parameter) appears more than once in the join
-      condition.  Specifically this allows the common task of a
-      relation() which contains a parent-correlated subquery, such
-      as "select only the most recent child item". [ticket:946]
-
-    - Fixed bug in polymorphic inheritance where an incorrect
-      exception is raised when base polymorphic_on column does not
-      correspond to any columns within the local selectable of an
-      inheriting mapper more than one level deep
-
-    - Fixed bug in polymorphic inheritance which made it difficult
-      to set a working "order_by" on a polymorphic mapper.
-
-    - Fixed a rather expensive call in Query that was slowing down
-      polymorphic queries.
-
-    - "Passive defaults" and other "inline" defaults can now be
-      loaded during a flush() call if needed; in particular, this
-      allows constructing relations() where a foreign key column
-      references a server-side-generated, non-primary-key
-      column. [ticket:954]
-
-    - Additional Session transaction fixes/changes:
-        - Fixed bug with session transaction management: parent
-          transactions weren't started on the connection when
-          adding a connection to a nested transaction.
-
-        - session.transaction now always refers to the innermost
-          active transaction, even when commit/rollback are called
-          directly on the session transaction object.
-
-        - Two-phase transactions can now be prepared.
-
-        - When preparing a two-phase transaction fails on one
-          connection, all the connections are rolled back.
-
-        - session.close() didn't close all transactions when
-          nested transactions were used.
-
-        - rollback() previously erroneously set the current
-          transaction directly to the parent of the transaction
-          that could be rolled back to. Now it rolls back the next
-          transaction up that can handle it, but sets the current
-          transaction to it's parent and inactivates the
-          transactions in between. Inactive transactions can only
-          be rolled back or closed, any other call results in an
-          error.
-
-        - autoflush for commit() wasn't flushing for simple
-          subtransactions.
-
-        - unitofwork flush didn't close the failed transaction
-          when the session was not in a transaction and commiting
-          the transaction failed.
-
-    - Miscellaneous tickets: [ticket:940] [ticket:964]
-
-- general
-    - Fixed a variety of hidden and some not-so-hidden
-      compatibility issues for Python 2.3, thanks to new support
-      for running the full test suite on 2.3.
-
-    - Warnings are now issued as type exceptions.SAWarning.
-
-- dialects
-    - Better support for schemas in SQLite (linked in by ATTACH
-      DATABASE ... AS name).  In some cases in the past, schema
-      names were ommitted from generated SQL for SQLite.  This is
-      no longer the case.
-
-    - table_names on SQLite now picks up temporary tables as well.
-
-    - Auto-detect an unspecified MySQL ANSI_QUOTES mode during
-      reflection operations, support for changing the mode
-      midstream.  Manual mode setting is still required if no
-      reflection is used.
-
-    - Fixed reflection of TIME columns on SQLite.
-
-    - Finally added PGMacAddr type to postgres [ticket:580]
-
-    - Reflect the sequence associated to a PK field (typically
-      with a BEFORE INSERT trigger) under Firebird
-
-    - Oracle assembles the correct columns in the result set
-      column mapping when generating a LIMIT/OFFSET subquery,
-      allows columns to map properly to result sets even if
-      long-name truncation kicks in [ticket:941]
-
-    - MSSQL now includes EXEC in the _is_select regexp, which
-      should allow row-returning stored procedures to be used.
-
-    - MSSQL now includes an experimental implementation of
-      LIMIT/OFFSET using the ANSI SQL row_number() function, so it
-      requires MSSQL-2005 or higher. To enable the feature, add
-      "has_window_funcs" to the keyword arguments for connect, or
-      add "?has_window_funcs=1" to your dburi query arguments.
-
-- ext
-    - Changed ext.activemapper to use a non-transactional session
-      for the objectstore.
-
-    - Fixed output order of "['a'] + obj.proxied" binary operation
-      on association-proxied lists.
-
-0.4.2p3
-------
-- general
-    - sub version numbering scheme changed to suite
-      setuptools version number rules; easy_install -u
-      should now get this version over 0.4.2.
-
-- sql
-    - Text type is properly exported now and does not
-      raise a warning on DDL create; String types with no
-      length only raise warnings during CREATE TABLE
-      [ticket:912]
-
-    - new UnicodeText type is added, to specify an
-      encoded, unlengthed Text type
-
-    - fixed bug in union() so that select() statements
-      which don't derive from FromClause objects can be
-      unioned
-
-- orm
-    - fixed bug with session.dirty when using "mutable
-      scalars" (such as PickleTypes)
-
-    - added a more descriptive error message when flushing
-      on a relation() that has non-locally-mapped columns
-      in its primary or secondary join condition
-
-- dialects
-    - Fixed reflection of mysql empty string column
-      defaults.
-
-0.4.2b  (0.4.2p2)
-------
-- sql
-    - changed name of TEXT to Text since its a "generic"
-      type; TEXT name is deprecated until 0.5. The
-      "upgrading" behavior of String to Text when no
-      length is present is also deprecated until 0.5; will
-      issue a warning when used for CREATE TABLE
-      statements (String with no length for SQL expression
-      purposes is still fine) [ticket:912]
-
-    - generative select.order_by(None) / group_by(None)
-      was not managing to reset order by/group by
-      criterion, fixed [ticket:924]
-
-- orm
-    - suppressing *all* errors in
-      InstanceState.__cleanup() now.
-
-    - fixed an attribute history bug whereby assigning a
-      new collection to a collection-based attribute which
-      already had pending changes would generate incorrect
-      history [ticket:922]
-
-    - fixed delete-orphan cascade bug whereby setting the
-      same object twice to a scalar attribute could log it
-      as an orphan [ticket:925]
-
-    - Fixed cascades on a += assignment to a list-based
-      relation.
-
-    - synonyms can now be created against props that don't
-      exist yet, which are later added via add_property().
-      This commonly includes backrefs. (i.e. you can make
-      synonyms for backrefs without worrying about the
-      order of operations) [ticket:919]
-
-    - fixed bug which could occur with polymorphic "union"
-      mapper which falls back to "deferred" loading of
-      inheriting tables
-
-    - the "columns" collection on a mapper/mapped class
-      (i.e. 'c') is against the mapped table, not the
-      select_table in the case of polymorphic "union"
-      loading (this shouldn't be noticeable).
-
-- ext
-    - '+', '*', '+=' and '*=' support for association
-      proxied lists.
-
-- dialects
-    - mssql - narrowed down the test for "date"/"datetime"
-      in MSDate/ MSDateTime subclasses so that incoming
-      "datetime" objects don't get mis-interpreted as
-      "date" objects and vice versa, [ticket:923]
-
-0.4.2a   (0.4.2p1)
-------
-
-- orm
-    - fixed fairly critical bug whereby the same instance could be listed
-      more than once in the unitofwork.new collection; most typically
-      reproduced when using a combination of inheriting mappers and
-      ScopedSession.mapper, as the multiple __init__ calls per instance
-      could save() the object with distinct _state objects
-
-    - added very rudimentary yielding iterator behavior to Query.  Call
-      query.yield_per(<number of rows>) and evaluate the Query in an
-      iterative context; every collection of N rows will be packaged up
-      and yielded.  Use this method with extreme caution since it does
-      not attempt to reconcile eagerly loaded collections across
-      result batch boundaries, nor will it behave nicely if the same
-      instance occurs in more than one batch.  This means that an eagerly
-      loaded collection will get cleared out if it's referenced in more than
-      one batch, and in all cases attributes will be overwritten on instances
-      that occur in more than one batch.
-
-   - Fixed in-place set mutation operators for set collections and association
-     proxied sets. [ticket:920]
-
-- dialects
-    - Fixed the missing call to subtype result processor for the PGArray
-      type. [ticket:913]
-
-0.4.2
------
-- sql
-    - generic functions ! we introduce a database of known SQL functions, such
-      as current_timestamp, coalesce, and create explicit function objects
-      representing them. These objects have constrained argument lists, are
-      type aware, and can compile in a dialect-specific fashion. So saying
-      func.char_length("foo", "bar") raises an error (too many args),
-      func.coalesce(datetime.date(2007, 10, 5), datetime.date(2005, 10, 15))
-      knows that its return type is a Date. We only have a few functions
-      represented so far but will continue to add to the system [ticket:615]
-
-    - auto-reconnect support improved; a Connection can now automatically
-      reconnect after its underlying connection is invalidated, without
-      needing to connect() again from the engine.  This allows an ORM session
-      bound to a single Connection to not need a reconnect.
-      Open transactions on the Connection must be rolled back after an invalidation
-      of the underlying connection else an error is raised.  Also fixed
-      bug where disconnect detect was not being called for cursor(), rollback(),
-      or commit().
-
-    - added new flag to String and create_engine(),
-      assert_unicode=(True|False|'warn'|None). Defaults to `False` or `None` on
-      create_engine() and String, `'warn'` on the Unicode type. When `True`,
-      results in all unicode conversion operations raising an exception when a
-      non-unicode bytestring is passed as a bind parameter. 'warn' results
-      in a warning. It is strongly advised that all unicode-aware applications
-      make proper use of Python unicode objects (i.e. u'hello' and not 'hello')
-      so that data round trips accurately.
-
-    - generation of "unique" bind parameters has been simplified to use the same
-      "unique identifier" mechanisms as everything else.  This doesn't affect
-      user code, except any code that might have been hardcoded against the generated
-      names.  Generated bind params now have the form "<paramname>_<num>",
-      whereas before only the second bind of the same name would have this form.
-
-    - select().as_scalar() will raise an exception if the select does not have
-      exactly one expression in its columns clause.
-
-    - bindparam() objects themselves can be used as keys for execute(), i.e.
-      statement.execute({bind1:'foo', bind2:'bar'})
-
-    - added new methods to TypeDecorator, process_bind_param() and
-      process_result_value(), which automatically take advantage of the processing
-      of the underlying type.  Ideal for using with Unicode or Pickletype.
-      TypeDecorator should now be the primary way to augment the behavior of any
-      existing type including other TypeDecorator subclasses such as PickleType.
-
-    - selectables (and others) will issue a warning when two columns in
-      their exported columns collection conflict based on name.
-
-    - tables with schemas can still be used in sqlite, firebird,
-      schema name just gets dropped [ticket:890]
-
-    - changed the various "literal" generation functions to use an anonymous
-      bind parameter.  not much changes here except their labels now look
-      like ":param_1", ":param_2" instead of ":literal"
-
-    - column labels in the form "tablename.columname", i.e. with a dot, are now
-      supported.
-
-    - from_obj keyword argument to select() can be a scalar or a list.
-
-- orm
-   - a major behavioral change to collection-based backrefs: they no
-     longer trigger lazy loads !  "reverse" adds and removes
-     are queued up and are merged with the collection when it is
-     actually read from and loaded; but do not trigger a load beforehand.
-     For users who have noticed this behavior, this should be much more
-     convenient than using dynamic relations in some cases; for those who
-     have not, you might notice your apps using a lot fewer queries than
-     before in some situations. [ticket:871]
-
-   - mutable primary key support is added. primary key columns can be
-     changed freely, and the identity of the instance will change upon
-     flush. In addition, update cascades of foreign key referents (primary
-     key or not) along relations are supported, either in tandem with the
-     database's ON UPDATE CASCADE (required for DB's like Postgres) or
-     issued directly by the ORM in the form of UPDATE statements, by setting
-     the flag "passive_cascades=False".
-
-   - inheriting mappers now inherit the MapperExtensions of their parent
-     mapper directly, so that all methods for a particular MapperExtension
-     are called for subclasses as well.  As always, any MapperExtension
-     can return either EXT_CONTINUE to continue extension processing
-     or EXT_STOP to stop processing.  The order of mapper resolution is:
-     <extensions declared on the classes mapper> <extensions declared on the
-     classes' parent mapper> <globally declared extensions>.
-
-     Note that if you instantiate the same extension class separately
-     and then apply it individually for two mappers in the same inheritance
-     chain, the extension will be applied twice to the inheriting class,
-     and each method will be called twice.
-
-     To apply a mapper extension explicitly to each inheriting class but
-     have each method called only once per operation, use the same
-     instance of the extension for both mappers.
-     [ticket:490]
-
-   - MapperExtension.before_update() and after_update() are now called
-     symmetrically; previously, an instance that had no modified column
-     attributes (but had a relation() modification) could be called with
-     before_update() but not after_update() [ticket:907]
-
-   - columns which are missing from a Query's select statement
-     now get automatically deferred during load.
-
-   - mapped classes which extend "object" and do not provide an
-     __init__() method will now raise TypeError if non-empty *args
-     or **kwargs are present at instance construction time (and are
-     not consumed by any extensions such as the scoped_session mapper),
-     consistent with the behavior of normal Python classes [ticket:908]
-
-   - fixed Query bug when filter_by() compares a relation against None
-     [ticket:899]
-
-   - improved support for pickling of mapped entities.  Per-instance
-     lazy/deferred/expired callables are now serializable so that
-     they serialize and deserialize with _state.
-
-   - new synonym() behavior: an attribute will be placed on the mapped
-     class, if one does not exist already, in all cases. if a property
-     already exists on the class, the synonym will decorate the property
-     with the appropriate comparison operators so that it can be used in in
-     column expressions just like any other mapped attribute (i.e. usable in
-     filter(), etc.) the "proxy=True" flag is deprecated and no longer means
-     anything. Additionally, the flag "map_column=True" will automatically
-     generate a ColumnProperty corresponding to the name of the synonym,
-     i.e.: 'somename':synonym('_somename', map_column=True) will map the
-     column named 'somename' to the attribute '_somename'. See the example
-     in the mapper docs. [ticket:801]
-
-   - Query.select_from() now replaces all existing FROM criterion with
-     the given argument; the previous behavior of constructing a list
-     of FROM clauses was generally not useful as is required
-     filter() calls to create join criterion, and new tables introduced
-     within filter() already add themselves to the FROM clause.  The
-     new behavior allows not just joins from the main table, but select
-     statements as well.  Filter criterion, order bys, eager load
-     clauses will be "aliased" against the given statement.
-
-   - this month's refactoring of attribute instrumentation changes
-     the "copy-on-load" behavior we've had since midway through 0.3
-     with "copy-on-modify" in most cases.  This takes a sizable chunk
-     of latency out of load operations and overall does less work
-     as only attributes which are actually modified get their
-     "committed state" copied.  Only "mutable scalar" attributes
-     (i.e. a pickled object or other mutable item), the reason for
-     the copy-on-load change in the first place, retain the old
-     behavior.
-
-   - a slight behavioral change to attributes is, del'ing an attribute
-     does *not* cause the lazyloader of that attribute to fire off again;
-     the "del" makes the effective value of the attribute "None".  To
-     re-trigger the "loader" for an attribute, use
-     session.expire(instance, [attrname]).
-
-   - query.filter(SomeClass.somechild == None), when comparing
-     a many-to-one property to None, properly generates "id IS NULL"
-     including that the NULL is on the right side.
-
-   - query.order_by() takes into account aliased joins, i.e.
-     query.join('orders', aliased=True).order_by(Order.id)
-
-   - eagerload(), lazyload(), eagerload_all() take an optional
-     second class-or-mapper argument, which will select the mapper
-     to apply the option towards.  This can select among other
-     mappers which were added using add_entity().
-
-   - eagerloading will work with mappers added via add_entity().
-
-   - added "cascade delete" behavior to "dynamic" relations just like
-     that of regular relations.  if passive_deletes flag (also just added)
-     is not set, a delete of the parent item will trigger a full load of
-     the child items so that they can be deleted or updated accordingly.
-
-   - also with dynamic, implemented correct count() behavior as well
-     as other helper methods.
-
-   - fix to cascades on polymorphic relations, such that cascades
-     from an object to a polymorphic collection continue cascading
-     along the set of attributes specific to each element in the collection.
-
-   - query.get() and query.load() do not take existing filter or other
-     criterion into account; these methods *always* look up the given id
-     in the database or return the current instance from the identity map,
-     disregarding any existing filter, join, group_by or other criterion
-     which has been configured. [ticket:893]
-
-   - added support for version_id_col in conjunction with inheriting mappers.
-     version_id_col is typically set on the base mapper in an inheritance
-     relationship where it takes effect for all inheriting mappers.
-     [ticket:883]
-
-   - relaxed rules on column_property() expressions having labels; any
-     ColumnElement is accepted now, as the compiler auto-labels non-labeled
-     ColumnElements now.  a selectable, like a select() statement, still
-     requires conversion to ColumnElement via as_scalar() or label().
-
-   - fixed backref bug where you could not del instance.attr if attr
-     was None
-
-   - several ORM attributes have been removed or made private:
-     mapper.get_attr_by_column(), mapper.set_attr_by_column(),
-     mapper.pks_by_table, mapper.cascade_callable(),
-     MapperProperty.cascade_callable(), mapper.canload(),
-     mapper.save_obj(), mapper.delete_obj(), mapper._mapper_registry,
-     attributes.AttributeManager
-
-   - Assigning an incompatible collection type to a relation attribute now
-     raises TypeError instead of sqlalchemy's ArgumentError.
-
-   - Bulk assignment of a MappedCollection now raises an error if a key in the
-     incoming dictionary does not match the key that the collection's keyfunc
-     would use for that value. [ticket:886]
-
-   - Custom collections can now specify a @converter method to translate
-     objects used in "bulk" assignment into a stream of values, as in::
-
-        obj.col = [newval1, newval2]
-        # or
-        obj.dictcol = {'foo': newval1, 'bar': newval2}
-
-     The MappedCollection uses this hook to ensure that incoming key/value
-     pairs are sane from the collection's perspective.
-
-   - fixed endless loop issue when using lazy="dynamic" on both
-     sides of a bi-directional relationship [ticket:872]
-
-   - more fixes to the LIMIT/OFFSET aliasing applied with Query + eagerloads,
-     in this case when mapped against a select statement [ticket:904]
-
-   - fix to self-referential eager loading such that if the same mapped
-     instance appears in two or more distinct sets of columns in the same
-     result set, its eagerly loaded collection will be populated regardless
-     of whether or not all of the rows contain a set of "eager" columns for
-     that collection.  this would also show up as a KeyError when fetching
-     results with join_depth turned on.
-
-   - fixed bug where Query would not apply a subquery to the SQL when LIMIT
-     was used in conjunction with an inheriting mapper where the eager
-     loader was only in the parent mapper.
-
-   - clarified the error message which occurs when you try to update()
-     an instance with the same identity key as an instance already present
-     in the session.
-
-   - some clarifications and fixes to merge(instance, dont_load=True).
-     fixed bug where lazy loaders were getting disabled on returned instances.
-     Also, we currently do not support merging an instance which has uncommitted
-     changes on it, in the case that dont_load=True is used....this will
-     now raise an error.  This is due to complexities in merging the
-     "committed state" of the given instance to correctly correspond to the
-     newly copied instance, as well as other modified state.
-     Since the use case for dont_load=True is caching, the given instances
-     shouldn't have any uncommitted changes on them anyway.
-     We also copy the instances over without using any events now, so that
-     the 'dirty' list on the new session remains unaffected.
-
-   - fixed bug which could arise when using session.begin_nested() in conjunction
-     with more than one level deep of enclosing session.begin() statements
-
-   - fixed session.refresh() with instance that has custom entity_name
-     [ticket:914]
-
-- dialects
-
-   - sqlite SLDate type will not erroneously render "microseconds" portion
-     of a datetime or time object.
-
-   - oracle
-      - added disconnect detection support for Oracle
-      - some cleanup to binary/raw types so that cx_oracle.LOB is detected
-        on an ad-hoc basis [ticket:902]
-
-   - MSSQL
-      - PyODBC no longer has a global "set nocount on".
-      - Fix non-identity integer PKs on autload [ticket:824]
-      - Better support for convert_unicode [ticket:839]
-      - Less strict date conversion for pyodbc/adodbapi [ticket:842]
-      - Schema-qualified tables / autoload [ticket:901]
-
-   - Firebird backend
-
-     - does properly reflect domains (partially fixing [ticket:410]) and
-       PassiveDefaults
-
-     - reverted to use default poolclass (was set to SingletonThreadPool in
-       0.4.0 [3562] for test purposes)
-
-     - map func.length() to 'char_length' (easily overridable with the UDF
-       'strlen' on old versions of Firebird)
-
-
-0.4.1
------
-
-- sql
-
-  - the "shortname" keyword parameter on bindparam() has been
-    deprecated.
-
-  - Added contains operator (generates a "LIKE %<other>%" clause).
-
-  - anonymous column expressions are automatically labeled.
-    e.g. select([x* 5]) produces "SELECT x * 5 AS anon_1".
-    This allows the labelname to be present in the cursor.description
-    which can then be appropriately matched to result-column processing
-    rules. (we can't reliably use positional tracking for result-column
-    matches since text() expressions may represent multiple columns).
-
-  - operator overloading is now controlled by TypeEngine objects - the
-    one built-in operator overload so far is String types overloading
-    '+' to be the string concatenation operator.
-    User-defined types can also define their own operator overloading
-    by overriding the adapt_operator(self, op) method.
-
-  - untyped bind parameters on the right side of a binary expression
-    will be assigned the type of the left side of the operation, to better
-    enable the appropriate bind parameter processing to take effect
-    [ticket:819]
-
-  - Removed regular expression step from most statement compilations.
-    Also fixes [ticket:833]
-
-  - Fixed empty (zero column) sqlite inserts, allowing inserts on
-    autoincrementing single column tables.
-
-  - Fixed expression translation of text() clauses; this repairs various
-    ORM scenarios where literal text is used for SQL expressions
-
-  - Removed ClauseParameters object; compiled.params returns a regular
-    dictionary now, as well as result.last_inserted_params() /
-    last_updated_params().
-
-  - Fixed INSERT statements w.r.t. primary key columns that have
-    SQL-expression based default generators on them; SQL expression
-    executes inline as normal but will not trigger a "postfetch" condition
-    for the column, for those DB's who provide it via cursor.lastrowid
-
-  - func. objects can be pickled/unpickled [ticket:844]
-
-  - rewrote and simplified the system used to "target" columns across
-    selectable expressions.  On the SQL side this is represented by the
-    "corresponding_column()" method. This method is used heavily by the ORM
-    to "adapt" elements of an expression to similar, aliased expressions,
-    as well as to target result set columns originally bound to a
-    table or selectable to an aliased, "corresponding" expression.  The new
-    rewrite features completely consistent and accurate behavior.
-
-  - Added a field ("info") for storing arbitrary data on schema items
-    [ticket:573]
-
-  - The "properties" collection on Connections has been renamed "info" to
-    match schema's writable collections.  Access is still available via
-    the "properties" name until 0.5.
-
-  - fixed the close() method on Transaction when using strategy='threadlocal'
-
-  - fix to compiled bind parameters to not mistakenly populate None
-    [ticket:853]
-
-  - <Engine|Connection>._execute_clauseelement becomes a public method
-    Connectable.execute_clauseelement
-
-- orm
-  - eager loading with LIMIT/OFFSET applied no longer adds the primary
-    table joined to a limited subquery of itself; the eager loads now
-    join directly to the subquery which also provides the primary table's
-    columns to the result set.  This eliminates a JOIN from all eager loads
-    with LIMIT/OFFSET.  [ticket:843]
-
-  - session.refresh() and session.expire() now support an additional argument
-    "attribute_names", a list of individual attribute keynames to be refreshed
-    or expired, allowing partial reloads of attributes on an already-loaded
-    instance. [ticket:802]
-
-  - added op() operator to instrumented attributes; i.e.
-    User.name.op('ilike')('%somename%') [ticket:767]
-
-  - Mapped classes may now define __eq__, __hash__, and __nonzero__ methods
-    with arbitrary semantics.  The orm now handles all mapped instances on
-    an identity-only basis. (e.g. 'is' vs '==') [ticket:676]
-
-  - the "properties" accessor on Mapper is removed; it now throws an informative
-    exception explaining the usage of mapper.get_property() and
-    mapper.iterate_properties
-
-  - added having() method to Query, applies HAVING to the generated statement
-    in the same way as filter() appends to the WHERE clause.
-
-  - The behavior of query.options() is now fully based on paths, i.e. an
-    option such as eagerload_all('x.y.z.y.x') will apply eagerloading to
-    only those paths, i.e. and not 'x.y.x'; eagerload('children.children')
-    applies only to exactly two-levels deep, etc. [ticket:777]
-
-  - PickleType will compare using `==` when set up with mutable=False,
-    and not the `is` operator.  To use `is` or any other comparator, send
-    in a custom comparison function using PickleType(comparator=my_custom_comparator).
-
-  - query doesn't throw an error if you use distinct() and an order_by()
-    containing UnaryExpressions (or other) together [ticket:848]
-
-  - order_by() expressions from joined tables are properly added to columns
-    clause when using distinct() [ticket:786]
-
-  - fixed error where Query.add_column() would not accept a class-bound
-    attribute as an argument; Query also raises an error if an invalid
-    argument was sent to add_column() (at instances() time) [ticket:858]
-
-  - added a little more checking for garbage-collection dereferences in
-    InstanceState.__cleanup() to reduce "gc ignored" errors on app
-    shutdown
-
-  - The session API has been solidified:
-
-    - It's an error to session.save() an object which is already
-      persistent [ticket:840]
-
-    - It's an error to session.delete() an object which is *not*
-      persistent.
-
-    - session.update() and session.delete() raise an error when updating
-      or deleting an instance that is already in the session with a
-      different identity.
-
-    - The session checks more carefully when determining "object X already
-      in another session"; e.g. if you pickle a series of objects and
-      unpickle (i.e. as in a Pylons HTTP session or similar), they can go
-      into a new session without any conflict
-
-    - merge() includes a keyword argument "dont_load=True".  setting this
-      flag will cause the merge operation to not load any data from the
-      database in response to incoming detached objects, and will accept
-      the incoming detached object as though it were already present in
-      that session.  Use this to merge detached objects from external
-      caching systems into the session.
-
-  - Deferred column attributes no longer trigger a load operation when the
-    attribute is assigned to.  In those cases, the newly assigned value
-    will be present in the flushes' UPDATE statement unconditionally.
-
-  - Fixed a truncation error when re-assigning a subset of a collection
-    (obj.relation = obj.relation[1:]) [ticket:834]
-
-  - De-cruftified backref configuration code, backrefs which step on
-    existing properties now raise an error [ticket:832]
-
-  - Improved behavior of add_property() etc., fixed [ticket:831] involving
-    synonym/deferred.
-
-  - Fixed clear_mappers() behavior to better clean up after itself.
-
-  - Fix to "row switch" behavior, i.e. when an INSERT/DELETE is combined
-    into a single UPDATE; many-to-many relations on the parent object
-    update properly.  [ticket:841]
-
-  - Fixed __hash__ for association proxy- these collections are unhashable,
-    just like their mutable Python counterparts.
-
-  - Added proxying of save_or_update, __contains__ and __iter__ methods for
-    scoped sessions.
-
-  - fixed very hard-to-reproduce issue where by the FROM clause of Query
-    could get polluted by certain generative calls [ticket:852]
-
-- dialects
-
-  - Added experimental support for MaxDB (versions >= 7.6.03.007 only).
-
-  - oracle will now reflect "DATE" as an OracleDateTime column, not
-    OracleDate
-
-  - added awareness of schema name in oracle table_names() function,
-    fixes metadata.reflect(schema='someschema') [ticket:847]
-
-  - MSSQL anonymous labels for selection of functions made deterministic
-
-  - sqlite will reflect "DECIMAL" as a numeric column.
-
-  - Made access dao detection more reliable [ticket:828]
-
-  - Renamed the Dialect attribute 'preexecute_sequences' to
-    'preexecute_pk_sequences'.  An attribute porxy is in place for
-    out-of-tree dialects using the old name.
-
-  - Added test coverage for unknown type reflection. Fixed sqlite/mysql
-    handling of type reflection for unknown types.
-
-  - Added REAL for mysql dialect (for folks exploiting the
-    REAL_AS_FLOAT sql mode).
-
-  - mysql Float, MSFloat and MSDouble constructed without arguments
-    now produce no-argument DDL, e.g.'FLOAT'.
-
-- misc
-
-  - Removed unused util.hash().
-
-
-0.4.0
------
-
-- (see 0.4.0beta1 for the start of major changes against 0.3,
-  as well as http://www.sqlalchemy.org/trac/wiki/WhatsNewIn04 )
-
-- Added initial Sybase support (mxODBC so far) [ticket:785]
-
-- Added partial index support for PostgreSQL. Use the postgres_where keyword
-  on the Index.
-
-- string-based query param parsing/config file parser understands
-  wider range of string values for booleans [ticket:817]
-
-- backref remove object operation doesn't fail if the other-side
-  collection doesn't contain the item, supports noload collections
-  [ticket:813]
-
-- removed __len__ from "dynamic" collection as it would require issuing
-  a SQL "count()" operation, thus forcing all list evaluations to issue
-  redundant SQL [ticket:818]
-
-- inline optimizations added to locate_dirty() which can greatly speed up
-  repeated calls to flush(), as occurs with autoflush=True [ticket:816]
-
-- The IdentifierPreprarer's _requires_quotes test is now regex based.  Any
-  out-of-tree dialects that provide custom sets of legal_characters or
-  illegal_initial_characters will need to move to regexes or override
-  _requires_quotes.
-
-- Firebird has supports_sane_rowcount and supports_sane_multi_rowcount set
-  to False due to ticket #370 (right way).
-
-- Improvements and fixes on Firebird reflection:
-  . FBDialect now mimics OracleDialect, regarding case-sensitivity of TABLE and
-    COLUMN names (see 'case_sensitive remotion' topic on this current file).
-  . FBDialect.table_names() doesn't bring system tables (ticket:796).
-  . FB now reflects Column's nullable property correctly.
-
-- Fixed SQL compiler's awareness of top-level column labels as used
-  in result-set processing; nested selects which contain the same column
-  names don't affect the result or conflict with result-column metadata.
-
-- query.get() and related functions (like many-to-one lazyloading)
-  use compile-time-aliased bind parameter names, to prevent
-  name conflicts with bind parameters that already exist in the
-  mapped selectable.
-
-- Fixed three- and multi-level select and deferred inheritance loading
-  (i.e. abc inheritance with no select_table), [ticket:795]
-
-- Ident passed to id_chooser in shard.py always a list.
-
-- The no-arg ResultProxy._row_processor() is now the class attribute
-  `_process_row`.
-
-- Added support for returning values from inserts and updates for
-  PostgreSQL 8.2+. [ticket:797]
-
-- PG reflection, upon seeing the default schema name being used explicitly
-  as the "schema" argument in a Table, will assume that this is the the
-  user's desired convention, and will explicitly set the "schema" argument
-  in foreign-key-related reflected tables, thus making them match only
-  with Table constructors that also use the explicit "schema" argument
-  (even though its the default schema).
-  In other words, SA assumes the user is being consistent in this usage.
-
-- fixed sqlite reflection of BOOL/BOOLEAN [ticket:808]
-
-- Added support for UPDATE with LIMIT on mysql.
-
-- null foreign key on a m2o doesn't trigger a lazyload [ticket:803]
-
-- oracle does not implicitly convert to unicode for non-typed result
-  sets (i.e. when no TypeEngine/String/Unicode type is even being used;
-  previously it was detecting DBAPI types and converting regardless).
-  should fix [ticket:800]
-
-- fix to anonymous label generation of long table/column names [ticket:806]
-
-- Firebird dialect now uses SingletonThreadPool as poolclass.
-
-- Firebird now uses dialect.preparer to format sequences names
-
-- Fixed breakage with postgres and multiple two-phase transactions. Two-phase
-  commits and and rollbacks didn't automatically end up with a new transaction
-  as the usual dbapi commits/rollbacks do. [ticket:810]
-
-- Added an option to the _ScopedExt mapper extension to not automatically
-  save new objects to session on object initialization.
-
-- fixed Oracle non-ansi join syntax
-
-- PickleType and Interval types (on db not supporting it natively) are now
-  slightly faster.
-
-- Added Float and Time types to Firebird (FBFloat and FBTime). Fixed
-  BLOB SUB_TYPE for TEXT and Binary types.
-
-- Changed the API for the in_ operator. in_() now accepts a single argument
-  that is a sequence of values or a selectable. The old API of passing in
-  values as varargs still works but is deprecated.
-
-
-0.4.0beta6
-----------
-
-- The Session identity map is now *weak referencing* by default, use
-  weak_identity_map=False to use a regular dict.  The weak dict we are using
-  is customized to detect instances which are "dirty" and maintain a
-  temporary strong reference to those instances until changes are flushed.
-
-- Mapper compilation has been reorganized such that most compilation occurs
-  upon mapper construction.  This allows us to have fewer calls to
-  mapper.compile() and also to allow class-based properties to force a
-  compilation (i.e. User.addresses == 7 will compile all mappers; this is
-  [ticket:758]).  The only caveat here is that an inheriting mapper now
-  looks for its inherited mapper upon construction; so mappers within
-  inheritance relationships need to be constructed in inheritance order
-  (which should be the normal case anyway).
-
-- added "FETCH" to the keywords detected by Postgres to indicate a
-  result-row holding statement (i.e. in addition to "SELECT").
-
-- Added full list of SQLite reserved keywords so that they get escaped
-  properly.
-
-- Tightened up the relationship between the Query's generation of "eager
-  load" aliases, and Query.instances() which actually grabs the eagerly
-  loaded rows.  If the aliases were not specifically generated for that
-  statement by EagerLoader, the EagerLoader will not take effect when the
-  rows are fetched.  This prevents columns from being grabbed accidentally
-  as being part of an eager load when they were not meant for such, which
-  can happen with textual SQL as well as some inheritance situations.  It's
-  particularly important since the "anonymous aliasing" of columns uses
-  simple integer counts now to generate labels.
-
-- Removed "parameters" argument from clauseelement.compile(), replaced with
-  "column_keys".  The parameters sent to execute() only interact with the
-  insert/update statement compilation process in terms of the column names
-  present but not the values for those columns.  Produces more consistent
-  execute/executemany behavior, simplifies things a bit internally.
-
-- Added 'comparator' keyword argument to PickleType.  By default, "mutable"
-  PickleType does a "deep compare" of objects using their dumps()
-  representation.  But this doesn't work for dictionaries.  Pickled objects
-  which provide an adequate __eq__() implementation can be set up with
-  "PickleType(comparator=operator.eq)" [ticket:560]
-
-- Added session.is_modified(obj) method; performs the same "history"
-  comparison operation as occurs within a flush operation; setting
-  include_collections=False gives the same result as is used when the flush
-  determines whether or not to issue an UPDATE for the instance's row.
-
-- Added "schema" argument to Sequence; use this with Postgres /Oracle when
-  the sequence is located in an alternate schema.  Implements part of
-  [ticket:584], should fix [ticket:761].
-
-- Fixed reflection of the empty string for mysql enums.
-
-- Changed MySQL dialect to use the older LIMIT <offset>, <limit> syntax
-  instead of LIMIT <l> OFFSET <o> for folks using 3.23. [ticket:794]
-
-- Added 'passive_deletes="all"' flag to relation(), disables all nulling-out
-  of foreign key attributes during a flush where the parent object is
-  deleted.
-
-- Column defaults and onupdates, executing inline, will add parenthesis for
-  subqueries and other parenthesis-requiring expressions
-
-- The behavior of String/Unicode types regarding that they auto-convert to
-  TEXT/CLOB when no length is present now occurs *only* for an exact type of
-  String or Unicode with no arguments.  If you use VARCHAR or NCHAR
-  (subclasses of String/Unicode) with no length, they will be interpreted by
-  the dialect as VARCHAR/NCHAR; no "magic" conversion happens there.  This
-  is less surprising behavior and in particular this helps Oracle keep
-  string-based bind parameters as VARCHARs and not CLOBs [ticket:793].
-
-- Fixes to ShardedSession to work with deferred columns [ticket:771].
-
-- User-defined shard_chooser() function must accept "clause=None" argument;
-  this is the ClauseElement passed to session.execute(statement) and can be
-  used to determine correct shard id (since execute() doesn't take an
-  instance.)
-
-- Adjusted operator precedence of NOT to match '==' and others, so that
-  ~(x <operator> y) produces NOT (x <op> y), which is better compatible
-  with older MySQL versions. [ticket:764].  This doesn't apply to "~(x==y)"
-  as it does in 0.3 since ~(x==y) compiles to "x != y", but still applies
-  to operators like BETWEEN.
-
-- Other tickets: [ticket:768], [ticket:728], [ticket:779], [ticket:757]
-
-0.4.0beta5
-----------
-
-- Connection pool fixes; the better performance of beta4 remains but fixes
-  "connection overflow" and other bugs which were present (like
-  [ticket:754]).
-
-- Fixed bugs in determining proper sync clauses from custom inherit
-  conditions. [ticket:769]
-
-- Extended 'engine_from_config' coercion for QueuePool size / overflow.
-  [ticket:763]
-
-- mysql views can be reflected again. [ticket:748]
-
-- AssociationProxy can now take custom getters and setters.
-
-- Fixed malfunctioning BETWEEN in orm queries.
-
-- Fixed OrderedProperties pickling [ticket:762]
-
-- SQL-expression defaults and sequences now execute "inline" for all
-  non-primary key columns during an INSERT or UPDATE, and for all columns
-  during an executemany()-style call. inline=True flag on any insert/update
-  statement also forces the same behavior with a single execute().
-  result.postfetch_cols() is a collection of columns for which the previous
-  single insert or update statement contained a SQL-side default expression.
-
-- Fixed PG executemany() behavior, [ticket:759]
-
-- postgres reflects tables with autoincrement=False for primary key columns
-  which have no defaults.
-
-- postgres no longer wraps executemany() with individual execute() calls,
-  instead favoring performance.  "rowcount"/"concurrency" checks with
-  deleted items (which use executemany) are disabled with PG since psycopg2
-  does not report proper rowcount for executemany().
-
-- Tickets fixed:
-
-  - [ticket:742]
-  - [ticket:748]
-  - [ticket:760]
-  - [ticket:762]
-  - [ticket:763]
-
-0.4.0beta4
-----------
-
-- Tidied up what ends up in your namespace when you 'from sqlalchemy import *':
-
-  - 'table' and 'column' are no longer imported.  They remain available by
-    direct reference (as in 'sql.table' and 'sql.column') or a glob import
-    from the sql package.  It was too easy to accidentally use a
-    sql.expressions.table instead of schema.Table when just starting out
-    with SQLAlchemy, likewise column.
-
-  - Internal-ish classes like ClauseElement, FromClause, NullTypeEngine,
-    etc., are also no longer imported into your namespace
-
-  - The 'Smallinteger' compatiblity name (small i!) is no longer imported,
-    but remains in schema.py for now.  SmallInteger (big I!) is still
-    imported.
-
-- The connection pool uses a "threadlocal" strategy internally to return
-  the same connection already bound to a thread, for "contextual" connections;
-  these are the connections used when you do a "connectionless" execution
-  like insert().execute().  This is like a "partial" version of the
-  "threadlocal" engine strategy but without the thread-local transaction part
-  of it.  We're hoping it reduces connection pool overhead as well as
-  database usage.  However, if it proves to impact stability in a negative way,
-  we'll roll it right back.
-
-- Fix to bind param processing such that "False" values (like blank strings)
-  still get processed/encoded.
-
-- Fix to select() "generative" behavior, such that calling column(),
-  select_from(), correlate(), and with_prefix() does not modify the
-  original select object [ticket:752]
-
-- Added a "legacy" adapter to types, such that user-defined TypeEngine
-  and TypeDecorator classes which define convert_bind_param() and/or
-  convert_result_value() will continue to function.  Also supports
-  calling the super() version of those methods.
-
-- Added session.prune(), trims away instances cached in a session that
-  are no longer referenced elsewhere. (A utility for strong-ref
-  identity maps).
-
-- Added close() method to Transaction.  Closes out a transaction using
-  rollback if it's the outermost transaction, otherwise just ends
-  without affecting the outer transaction.
-
-- Transactional and non-transactional Session integrates better with
-  bound connection; a close() will ensure that connection
-  transactional state is the same as that which existed on it before
-  being bound to the Session.
-
-- Modified SQL operator functions to be module-level operators,
-  allowing SQL expressions to be pickleable. [ticket:735]
-
-- Small adjustment to mapper class.__init__ to allow for Py2.6
-  object.__init__() behavior.
-
-- Fixed 'prefix' argument for select()
-
-- Connection.begin() no longer accepts nested=True, this logic is now
-  all in begin_nested().
-
-- Fixes to new "dynamic" relation loader involving cascades
-
-- Tickets fixed:
-
-  - [ticket:735]
-  - [ticket:752]
-
-0.4.0beta3
-----------
-
-- SQL types optimization:
-
-  - New performance tests show a combined mass-insert/mass-select test as
-    having 68% fewer function calls than the same test run against 0.3.
-
-  - General performance improvement of result set iteration is around 10-20%.
-
-  - In types.AbstractType, convert_bind_param() and convert_result_value()
-    have migrated to callable-returning bind_processor() and
-    result_processor() methods.  If no callable is returned, no pre/post
-    processing function is called.
-
-  - Hooks added throughout base/sql/defaults to optimize the calling of bind
-    aram/result processors so that method call overhead is minimized.
-
-  - Support added for executemany() scenarios such that unneeded "last row id"
-    logic doesn't kick in, parameters aren't excessively traversed.
-
-- Added 'inherit_foreign_keys' arg to mapper().
-
-- Added support for string date passthrough in sqlite.
-
-- Tickets fixed:
-
-  - [ticket:738]
-  - [ticket:739]
-  - [ticket:743]
-  - [ticket:744]
-
-0.4.0beta2
-----------
-
-- mssql improvements.
-
-- oracle improvements.
-
-- Auto-commit after LOAD DATA INFILE for mysql.
-
-- A rudimental SessionExtension class has been added, allowing user-defined
-  functionality to take place at flush(), commit(), and rollback() boundaries.
-
-- Added engine_from_config() function for helping to create_engine() from an
-  .ini style config.
-
-- base_mapper() becomes a plain attribute.
-
-- session.execute() and scalar() can search for a Table with which to bind from
-  using the given ClauseElement.
-
-- Session automatically extrapolates tables from mappers with binds, also uses
-  base_mapper so that inheritance hierarchies bind automatically.
-
-- Moved ClauseVisitor traversal back to inlined non-recursive.
-
-- Tickets fixed:
-
-  - [ticket:730]
-  - [ticket:732]
-  - [ticket:733]
-  - [ticket:734]
-
-0.4.0beta1
-----------
-
-- orm
-
-  - Speed! Along with recent speedups to ResultProxy, total number of function
-    calls significantly reduced for large loads.
-
-  - test/perf/masseagerload.py reports 0.4 as having the fewest number of
-    function calls across all SA versions (0.1, 0.2, and 0.3).
-
-  - New collection_class api and implementation [ticket:213]. Collections are
-    now instrumented via decorations rather than proxying.  You can now have
-    collections that manage their own membership, and your class instance will
-    be directly exposed on the relation property.  The changes are transparent
-    for most users.
-
-    - InstrumentedList (as it was) is removed, and relation properties no
-      longer have 'clear()', '.data', or any other added methods beyond those
-      provided by the collection type. You are free, of course, to add them to
-      a custom class.
-
-    - __setitem__-like assignments now fire remove events for the existing
-      value, if any.
-
-    - dict-likes used as collection classes no longer need to change __iter__
-      semantics- itervalues() is used by default instead. This is a backwards
-      incompatible change.
-
-    - Subclassing dict for a mapped collection is no longer needed in most
-      cases. orm.collections provides canned implementations that key objects
-      by a specified column or a custom function of your choice.
-
-    - Collection assignment now requires a compatible type- assigning None to
-      clear a collection or assigning a list to a dict collection will now
-      raise an argument error.
-
-    - AttributeExtension moved to interfaces, and .delete is now .remove The
-      event method signature has also been swapped around.
-
-  - Major overhaul for Query:
-
-    - All selectXXX methods are deprecated.  Generative methods are now the
-      standard way to do things, i.e. filter(), filter_by(), all(), one(),
-      etc.  Deprecated methods are docstring'ed with their new replacements.
-
-    - Class-level properties are now usable as query elements... no more
-      '.c.'!  "Class.c.propname" is now superceded by "Class.propname".  All
-      clause operators are supported, as well as higher level operators such
-      as Class.prop==<some instance> for scalar attributes,
-      Class.prop.contains(<some instance>) and Class.prop.any(<some
-      expression>) for collection-based attributes (all are also
-      negatable).  Table-based column expressions as well as columns mounted
-      on mapped classes via 'c' are of course still fully available and can be
-      freely mixed with the new attributes.  [ticket:643]
-
-    - Removed ancient query.select_by_attributename() capability.
-
-    - The aliasing logic used by eager loading has been generalized, so that
-      it also adds full automatic aliasing support to Query.  It's no longer
-      necessary to create an explicit Alias to join to the same tables
-      multiple times; *even for self-referential relationships*.
-
-      - join() and outerjoin() take arguments "aliased=True".  Yhis causes
-        their joins to be built on aliased tables; subsequent calls to
-        filter() and filter_by() will translate all table expressions (yes,
-        real expressions using the original mapped Table) to be that of the
-        Alias for the duration of that join() (i.e. until reset_joinpoint() or
-        another join() is called).
-
-      - join() and outerjoin() take arguments "id=<somestring>".  When used
-        with "aliased=True", the id can be referenced by add_entity(cls,
-        id=<somestring>) so that you can select the joined instances even if
-        they're from an alias.
-
-      - join() and outerjoin() now work with self-referential relationships!
-        Using "aliased=True", you can join as many levels deep as desired,
-        i.e. query.join(['children', 'children'], aliased=True); filter
-        criterion will be against the rightmost joined table
-
-    - Added query.populate_existing(), marks the query to reload all
-      attributes and collections of all instances touched in the query,
-      including eagerly-loaded entities.  [ticket:660]
-
-    - Added eagerload_all(), allows eagerload_all('x.y.z') to specify eager
-      loading of all properties in the given path.
-
-  - Major overhaul for Session:
-
-    - New function which "configures" a session called "sessionmaker()".  Send
-      various keyword arguments to this function once, returns a new class
-      which creates a Session against that stereotype.
-
-    - SessionTransaction removed from "public" API.  You now can call begin()/
-      commit()/rollback() on the Session itself.
-
-    - Session also supports SAVEPOINT transactions; call begin_nested().
-
-    - Session supports two-phase commit behavior when vertically or
-      horizontally partitioning (i.e., using more than one engine).  Use
-      twophase=True.
-
-    - Session flag "transactional=True" produces a session which always places
-      itself into a transaction when first used.  Upon commit(), rollback() or
-      close(), the transaction ends; but begins again on the next usage.
-
-    - Session supports "autoflush=True".  This issues a flush() before each
-      query.  Use in conjunction with transactional, and you can just
-      save()/update() and then query, the new objects will be there.  Use
-      commit() at the end (or flush() if non-transactional) to flush remaining
-      changes.
-
-    - New scoped_session() function replaces SessionContext and assignmapper.
-      Builds onto "sessionmaker()" concept to produce a class whos Session()
-      construction returns the thread-local session.  Or, call all Session
-      methods as class methods, i.e. Session.save(foo); Session.commit().
-      just like the old "objectstore" days.
-
-    - Added new "binds" argument to Session to support configuration of
-      multiple binds with sessionmaker() function.
-
-    - A rudimental SessionExtension class has been added, allowing
-      user-defined functionality to take place at flush(), commit(), and
-      rollback() boundaries.
-
-  - Query-based relation()s available with dynamic_loader().  This is a
-    *writable* collection (supporting append() and remove()) which is also a
-    live Query object when accessed for reads.  Ideal for dealing with very
-    large collections where only partial loading is desired.
-
-  - flush()-embedded inline INSERT/UPDATE expressions.  Assign any SQL
-    expression, like "sometable.c.column + 1", to an instance's attribute.
-    Upon flush(), the mapper detects the expression and embeds it directly in
-    the INSERT or UPDATE statement; the attribute gets deferred on the
-    instance so it loads the new value the next time you access it.
-
-  - A rudimental sharding (horizontal scaling) system is introduced.  This
-    system uses a modified Session which can distribute read and write
-    operations among multiple databases, based on user-defined functions
-    defining the "sharding strategy".  Instances and their dependents can be
-    distributed and queried among multiple databases based on attribute
-    values, round-robin approaches or any other user-defined
-    system. [ticket:618]
-
-  - Eager loading has been enhanced to allow even more joins in more places.
-    It now functions at any arbitrary depth along self-referential and
-    cyclical structures.  When loading cyclical structures, specify
-    "join_depth" on relation() indicating how many times you'd like the table
-    to join to itself; each level gets a distinct table alias.  The alias
-    names themselves are generated at compile time using a simple counting
-    scheme now and are a lot easier on the eyes, as well as of course
-    completely deterministic. [ticket:659]
-
-  - Added composite column properties.  This allows you to create a type which
-    is represented by more than one column, when using the ORM.  Objects of
-    the new type are fully functional in query expressions, comparisons,
-    query.get() clauses, etc. and act as though they are regular single-column
-    scalars... except they're not!  Use the function composite(cls, *columns)
-    inside of the mapper's "properties" dict, and instances of cls will be
-    created/mapped to a single attribute, comprised of the values correponding
-    to *columns. [ticket:211]
-
-  - Improved support for custom column_property() attributes which feature
-    correlated subqueries, works better with eager loading now.
-
-  - Primary key "collapse" behavior; the mapper will analyze all columns in
-    its given selectable for primary key "equivalence", that is, columns which
-    are equivalent via foreign key relationship or via an explicit
-    inherit_condition. primarily for joined-table inheritance scenarios where
-    different named PK columns in inheriting tables should "collapse" into a
-    single-valued (or fewer-valued) primary key.  Fixes things like
-    [ticket:611].
-
-  - Joined-table inheritance will now generate the primary key columns of all
-    inherited classes against the root table of the join only.  This implies
-    that each row in the root table is distinct to a single instance.  If for
-    some rare reason this is not desireable, explicit primary_key settings on
-    individual mappers will override it.
-
-  - When "polymorphic" flags are used with joined-table or single-table
-    inheritance, all identity keys are generated against the root class of the
-    inheritance hierarchy; this allows query.get() to work polymorphically
-    using the same caching semantics as a non-polymorphic get.  Note that this
-    currently does not work with concrete inheritance.
-
-  - Secondary inheritance loading: polymorphic mappers can be constructed
-    *without* a select_table argument. inheriting mappers whose tables were
-    not represented in the initial load will issue a second SQL query
-    immediately, once per instance (i.e. not very efficient for large lists),
-    in order to load the remaining columns.
-
-  - Secondary inheritance loading can also move its second query into a
-    column-level "deferred" load, via the "polymorphic_fetch" argument, which
-    can be set to 'select' or 'deferred'
-
-  - It's now possible to map only a subset of available selectable columns
-    onto mapper properties, using include_columns/exclude_columns.
-    [ticket:696].
-
-  - Added undefer_group() MapperOption, sets a set of "deferred" columns
-    joined by a "group" to load as "undeferred".
-
-  - Rewrite of the "deterministic alias name" logic to be part of the SQL
-    layer, produces much simpler alias and label names more in the style of
-    Hibernate
-
-- sql
-
-  - Speed!  Clause compilation as well as the mechanics of SQL constructs have
-    been streamlined and simplified to a signficant degree, for a 20-30%
-    improvement of the statement construction/compilation overhead of 0.3.
-
-  - All "type" keyword arguments, such as those to bindparam(), column(),
-    Column(), and func.<something>(), renamed to "type_".  Those objects still
-    name their "type" attribute as "type".
-
-  - case_sensitive=(True|False) setting removed from schema items, since
-    checking this state added a lot of method call overhead and there was no
-    decent reason to ever set it to False.  Table and column names which are
-    all lower case will be treated as case-insenstive (yes we adjust for
-    Oracle's UPPERCASE style too).
-
-  - Transactions:
-
-    - Added context manager (with statement) support for transactions.
-    - Added support for two phase commit, works with mysql and postgres so far.
-    - Added a subtransaction implementation that uses savepoints.
-    - Added support for savepoints.
-
-  - MetaData:
-
-    - Tables can be reflected from the database en-masse without declaring
-      them in advance.  MetaData(engine, reflect=True) will load all tables
-      present in the database, or use metadata.reflect() for finer control.
-    - DynamicMetaData has been renamed to ThreadLocalMetaData
-    - The ThreadLocalMetaData constructor now takes no arguments.
-    - BoundMetaData has been removed- regular MetaData is equivalent
-
-  - Numeric and Float types now have an "asdecimal" flag; defaults to True for
-    Numeric, False for Float.  When True, values are returned as
-    decimal.Decimal objects; when False, values are returned as float().  The
-    defaults of True/False are already the behavior for PG and MySQL's DBAPI
-    modules. [ticket:646]
-
-  - New SQL operator implementation which removes all hardcoded operators from
-    expression structures and moves them into compilation; allows greater
-    flexibility of operator compilation; for example, "+" compiles to "||"
-    when used in a string context, or "concat(a,b)" on MySQL; whereas in a
-    numeric context it compiles to "+".  Fixes [ticket:475].
-
-  - "Anonymous" alias and label names are now generated at SQL compilation
-    time in a completely deterministic fashion... no more random hex IDs
-
-  - Significant architectural overhaul to SQL elements (ClauseElement).  All
-    elements share a common "mutability" framework which allows a consistent
-    approach to in-place modifications of elements as well as generative
-    behavior.  Improves stability of the ORM which makes heavy usage of
-    mutations to SQL expressions.
-
-  - select() and union()'s now have "generative" behavior.  Methods like
-    order_by() and group_by() return a *new* instance - the original instance
-    is left unchanged.  Non-generative methods remain as well.
-
-  - The internals of select/union vastly simplified- all decision making
-    regarding "is subquery" and "correlation" pushed to SQL generation phase.
-    select() elements are now *never* mutated by their enclosing containers or
-    by any dialect's compilation process [ticket:52] [ticket:569]
-
-  - select(scalar=True) argument is deprecated; use select(..).as_scalar().
-    The resulting object obeys the full "column" interface and plays better
-    within expressions.
-
-  - Added select().with_prefix('foo') allowing any set of keywords to be
-    placed before the columns clause of the SELECT [ticket:504]
-
-  - Added array slice support to row[<index>] [ticket:686]
-
-  - Result sets make a better attempt at matching the DBAPI types present in
-    cursor.description to the TypeEngine objects defined by the dialect, which
-    are then used for result-processing. Note this only takes effect for
-    textual SQL; constructed SQL statements always have an explicit type map.
-
-  - Result sets from CRUD operations close their underlying cursor immediately
-    and will also autoclose the connection if defined for the operation; this
-    allows more efficient usage of connections for successive CRUD operations
-    with less chance of "dangling connections".
-
-  - Column defaults and onupdate Python functions (i.e. passed to
-    ColumnDefault) may take zero or one arguments; the one argument is the
-    ExecutionContext, from which you can call "context.parameters[someparam]"
-    to access the other bind parameter values affixed to the statement
-    [ticket:559].  The connection used for the execution is available as well
-    so that you can pre-execute statements.
-
-  - Added "explcit" create/drop/execute support for sequences (i.e. you can
-    pass a "connectable" to each of those methods on Sequence).
-
-  - Better quoting of identifiers when manipulating schemas.
-
-  - Standardized the behavior for table reflection where types can't be
-    located; NullType is substituted instead, warning is raised.
-
-  - ColumnCollection (i.e. the 'c' attribute on tables) follows dictionary
-    semantics for "__contains__" [ticket:606]
-
-- engines
-
-  - Speed! The mechanics of result processing and bind parameter processing
-    have been overhauled, streamlined and optimized to issue as little method
-    calls as possible.  Bench tests for mass INSERT and mass rowset iteration
-    both show 0.4 to be over twice as fast as 0.3, using 68% fewer function
-    calls.
-
-  - You can now hook into the pool lifecycle and run SQL statements or other
-    logic at new each DBAPI connection, pool check-out and check-in.
-
-  - Connections gain a .properties collection, with contents scoped to the
-    lifetime of the underlying DBAPI connection
-
-  - Removed auto_close_cursors and disallow_open_cursors arguments from Pool;
-    reduces overhead as cursors are normally closed by ResultProxy and
-    Connection.
-
-- extensions
-
-  - proxyengine is temporarily removed, pending an actually working
-    replacement.
-
-  - SelectResults has been replaced by Query.  SelectResults /
-    SelectResultsExt still exist but just return a slightly modified Query
-    object for backwards-compatibility.  join_to() method from SelectResults
-    isn't present anymore, need to use join().
-
-- mysql
-
-  - Table and column names loaded via reflection are now Unicode.
-
-  - All standard column types are now supported, including SET.
-
-  - Table reflection can now be performed in as little as one round-trip.
-
-  - ANSI and ANSI_QUOTES sql modes are now supported.
-
-  - Indexes are now reflected.
-
-- postgres
-
-  - Added PGArray datatype for using postgres array datatypes.
-
-- oracle
-
-  - Very rudimental support for OUT parameters added; use sql.outparam(name,
-    type) to set up an OUT parameter, just like bindparam(); after execution,
-    values are avaiable via result.out_parameters dictionary. [ticket:507]
-
-0.3.11
-------
-
-- sql
-
-    - tweak DISTINCT precedence for clauses like
-      `func.count(t.c.col.distinct())`
-
-    - Fixed detection of internal '$' characters in :bind$params [ticket:719]
-
-    - [ticket:768] dont assume join criterion consists only of column objects
-
-    - adjusted operator precedence of NOT to match '==' and others, so that
-      ~(x==y) produces NOT (x=y), which is compatible with MySQL < 5.0
-      (doesn't like "NOT x=y") [ticket:764]
-
-- orm
-
-    - added a check for joining from A->B using join(), along two
-      different m2m tables.  this raises an error in 0.3 but is
-      possible in 0.4 when aliases are used. [ticket:687]
-
-    - fixed small exception throw bug in Session.merge()
-
-    - fixed bug where mapper, being linked to a join where one table had
-      no PK columns, would not detect that the joined table had no PK.
-
-    - fixed bugs in determining proper sync clauses from custom inherit
-      conditions [ticket:769]
-
-    - backref remove object operation doesn't fail if the other-side
-      collection doesn't contain the item, supports noload collections
-      [ticket:813]
-
-- engine
-
-    - fixed another occasional race condition which could occur
-      when using pool with threadlocal setting
-
-- mysql
-    - fixed specification of YEAR columns when generating schema
-
-- mssql
-
-    - added support for TIME columns (simulated using DATETIME) [ticket:679]
-
-    - added support for BIGINT, MONEY, SMALLMONEY, UNIQUEIDENTIFIER and
-      SQL_VARIANT [ticket:721]
-
-    - index names are now quoted when dropping from reflected tables
-      [ticket:684]
-
-    - can now specify a DSN for PyODBC, using a URI like mssql:///?dsn=bob
-
-- postgres
-
-    - when reflecting tables from alternate schemas, the "default" placed upon
-      the primary key, i.e. usually a sequence name, has the "schema" name
-      unconditionally quoted, so that schema names which need quoting are fine.
-      its slightly unnecessary for schema names which don't need quoting
-      but not harmful.
-
-- sqlite
-   - passthrough for stringified dates
-
-- firebird
-    - supports_sane_rowcount() set to False due to ticket #370 (right way).
-    - fixed reflection of Column's nullable property.
-
-- oracle
-    - removed LONG_STRING, LONG_BINARY from "binary" types, so type objects
-      don't try to read their values as LOB [ticket:622], [ticket:751]
-
-0.3.10
-- general
-    - a new mutex that was added in 0.3.9 causes the pool_timeout
-      feature to fail during a race condition; threads would
-      raise TimeoutError immediately with no delay if many threads
-      push the pool into overflow at the same time.  this issue has been
-      fixed.
-- sql
-  - got connection-bound metadata to work with implicit execution
-  - foreign key specs can have any chararcter in their identifiers
-   [ticket:667]
-  - added commutativity-awareness to binary clause comparisons to
-    each other, improves ORM lazy load optimization [ticket:664]
-- orm
-  - cleanup to connection-bound sessions, SessionTransaction
-- postgres
-  - fixed max identifier length (63) [ticket:571]
-
-
-0.3.9
-- general
-    - better error message for NoSuchColumnError [ticket:607]
-    - finally figured out how to get setuptools version in, available
-      as sqlalchemy.__version__ [ticket:428]
-    - the various "engine" arguments, such as "engine", "connectable",
-      "engine_or_url", "bind_to", etc. are all present, but deprecated.
-      they all get replaced by the single term "bind".  you also
-      set the "bind" of MetaData using
-      metadata.bind = <engine or connection>
-- ext
-    - iteration over dict association proxies is now dict-like, not
-      InstrumentedList-like (e.g. over keys instead of values)
-    - association proxies no longer bind tightly to source collections
-      [ticket:597], and are constructed with a thunk instead
-    - added selectone_by() to assignmapper
-- orm
-    - forwards-compatibility with 0.4: added one(), first(), and
-      all() to Query.  almost all Query functionality from 0.4 is
-      present in 0.3.9 for forwards-compat purposes.
-    - reset_joinpoint() really really works this time, promise ! lets
-      you re-join from the root:
-      query.join(['a', 'b']).filter(<crit>).reset_joinpoint().\
-      join(['a', 'c']).filter(<some other crit>).all()
-      in 0.4 all join() calls start from the "root"
-    - added synchronization to the mapper() construction step, to avoid
-      thread collisions when pre-existing mappers are compiling in a
-      different thread [ticket:613]
-    - a warning is issued by Mapper when two primary key columns of the
-      same name are munged into a single attribute.  this happens frequently
-      when mapping to joins (or inheritance).
-    - synonym() properties are fully supported by all Query joining/
-      with_parent operations [ticket:598]
-    - fixed very stupid bug when deleting items with many-to-many
-      uselist=False relations
-    - remember all that stuff about polymorphic_union ?  for
-      joined table inheritance ?  Funny thing...
-      You sort of don't need it for joined table inheritance, you
-      can just string all the tables together via outerjoin().
-      The UNION still applies if concrete tables are involved,
-      though (since nothing to join them on).
-    - small fix to eager loading to better work with eager loads
-      to polymorphic mappers that are using a straight "outerjoin"
-      clause
-- sql
-    - ForeignKey to a table in a schema thats not the default schema
-      requires the schema to be explicit; i.e. ForeignKey('alt_schema.users.id')
-    - MetaData can now be constructed with an engine or url as the first
-      argument, just like BoundMetaData
-    - BoundMetaData is now deprecated, and MetaData is a direct substitute.
-    - DynamicMetaData has been renamed to ThreadLocalMetaData.  the
-      DynamicMetaData name is deprecated and is an alias for ThreadLocalMetaData
-      or a regular MetaData if threadlocal=False
-    - composite primary key is represented as a non-keyed set to allow for
-      composite keys consisting of cols with the same name; occurs within a
-      Join.  helps inheritance scenarios formulate correct PK.
-    - improved ability to get the "correct" and most minimal set of primary key
-      columns from a join, equating foreign keys and otherwise equated columns.
-      this is also mostly to help inheritance scenarios formulate the best
-      choice of primary key columns.  [ticket:185]
-    - added 'bind' argument to Sequence.create()/drop(), ColumnDefault.execute()
-    - columns can be overridden in a reflected table with a "key"
-      attribute different than the column's name, including for primary key
-      columns [ticket:650]
-    - fixed "ambiguous column" result detection, when dupe col names exist
-      in a result [ticket:657]
-    - some enhancements to "column targeting", the ability to match a column
-      to a "corresponding" column in another selectable.  this affects mostly
-      ORM ability to map to complex joins
-    - MetaData and all SchemaItems are safe to use with pickle.  slow
-      table reflections can be dumped into a pickled file to be reused later.
-      Just reconnect the engine to the metadata after unpickling. [ticket:619]
-    - added a mutex to QueuePool's "overflow" calculation to prevent a race
-      condition that can bypass max_overflow
-    - fixed grouping of compound selects to give correct results. will break
-      on sqlite in some cases, but those cases were producing incorrect
-      results anyway, sqlite doesn't support grouped compound selects
-      [ticket:623]
-    - fixed precedence of operators so that parenthesis are correctly applied
-      [ticket:620]
-    - calling <column>.in_() (i.e. with no arguments) will return
-      "CASE WHEN (<column> IS NULL) THEN NULL ELSE 0 END = 1)", so that
-      NULL or False is returned in all cases, rather than throwing an error
-      [ticket:545]
-    - fixed "where"/"from" criterion of select() to accept a unicode string
-      in addition to regular string - both convert to text()
-    - added standalone distinct() function in addition to column.distinct()
-      [ticket:558]
-    - result.last_inserted_ids() should return a list that is identically
-      sized to the primary key constraint of the table.  values that were
-      "passively" created and not available via cursor.lastrowid will be None.
-    - long-identifier detection fixed to use > rather than >= for
-      max ident length [ticket:589]
-    - fixed bug where selectable.corresponding_column(selectable.c.col)
-      would not return selectable.c.col, if the selectable is a join
-      of a table and another join involving the same table.  messed
-      up ORM decision making [ticket:593]
-    - added Interval type to types.py [ticket:595]
-- mysql
-    - fixed catching of some errors that imply a dropped connection [ticket:625]
-    - fixed escaping of the modulo operator [ticket:624]
-    - added 'fields' to reserved words [ticket:590]
-    - various reflection enhancement/fixes
-- oracle
-    - datetime fixes: got subsecond TIMESTAMP to work [ticket:604],
-      added OracleDate which supports types.Date with only year/month/day
-    - added dialect flag "auto_convert_lobs", defaults to True; will cause any
-      LOB objects detected in a result set to be forced into OracleBinary
-      so that the LOB is read() automatically, if no typemap was present
-      (i.e., if a textual execute() was issued).
-    - mod operator '%' produces MOD [ticket:624]
-    - converts cx_oracle datetime objects to Python datetime.datetime when
-      Python 2.3 used [ticket:542]
-    - fixed unicode conversion in Oracle TEXT type
-- postgres
-    - fixed escaping of the modulo operator [ticket:624]
-    - added support for reflection of domains [ticket:570]
-    - types which are missing during reflection resolve to Null type
-      instead of raising an error
-    - the fix in "schema" above fixes reflection of foreign keys from an
-      alt-schema table to a public schema table
-- sqlite
-    - rearranged dialect initialization so it has time to warn about pysqlite1
-      being too old.
-    - sqlite better handles datetime/date/time objects mixed and matched
-      with various Date/Time/DateTime columns
-    - string PK column inserts dont get overwritten with OID [ticket:603]
-- mssql
-    - fix port option handling for pyodbc [ticket:634]
-    - now able to reflect start and increment values for identity columns
-    - preliminary support for using scope_identity() with pyodbc
-
-0.3.8
-- engines
-  - added detach() to Connection, allows underlying DBAPI connection
-    to be detached from its pool, closing on dereference/close()
-    instead of being reused by the pool.
-  - added invalidate() to Connection, immediately invalidates the
-    Connection and its underlying DBAPI connection.
-- sql
-  - _Label class overrides compare_self to return its ultimate
-    object. meaning, if you say someexpr.label('foo') == 5, it
-    produces the correct "someexpr == 5".
-  - _Label propagates "_hide_froms()" so that scalar selects
-    behave more properly with regards to FROM clause #574
-  - fix to long name generation when using oid_column as an order by
-    (oids used heavily in mapper queries)
-  - significant speed improvement to ResultProxy, pre-caches
-    TypeEngine dialect implementations and saves on function calls
-    per column
-  - parenthesis are applied to clauses via a new _Grouping
-    construct. uses operator precedence to more intelligently apply
-    parenthesis to clauses, provides cleaner nesting of clauses
-    (doesnt mutate clauses placed in other clauses, i.e. no 'parens'
-    flag)
-  - added 'modifier' keyword, works like func.<foo> except does not
-    add parenthesis.  e.g. select([modifier.DISTINCT(...)]) etc.
-  - removed "no group by's in a select thats part of a UNION"
-    restriction [ticket:578]
-- orm
-  - added reset_joinpoint() method to Query, moves the "join point"
-    back to the starting mapper. 0.4 will change the behavior of
-    join() to reset the "join point" in all cases so this is an
-    interim method. for forwards compatibility, ensure joins across
-    multiple relations are specified using a single join(), i.e.
-    join(['a', 'b', 'c']).
-  - fixed bug in query.instances() that wouldnt handle more than
-    on additional mapper or one additional column.
-  - "delete-orphan" no longer implies "delete". ongoing effort to
-    separate the behavior of these two operations.
-  - many-to-many relationships properly set the type of bind params
-    for delete operations on the association table
-  - many-to-many relationships check that the number of rows deleted
-    from the association table by a delete operation matches the
-    expected results
-  - session.get() and session.load() propagate **kwargs through to
-    query
-  - fix to polymorphic query which allows the original
-    polymorphic_union to be embedded into a correlated subquery
-    [ticket:577]
-  - fix to select_by(<propname>=<object instance>) -style joins in
-    conjunction with many-to-many relationships, bug introduced in
-    r2556
-  - the "primary_key" argument to mapper() is propagated to the
-    "polymorphic" mapper. primary key columns in this list get
-    normalized to that of the mapper's local table.
-  - restored logging of "lazy loading clause" under
-    sa.orm.strategies logger, got removed in 0.3.7
-  - improved support for eagerloading of properties off of mappers
-    that are mapped to select() statements; i.e. eagerloader is
-    better at locating the correct selectable with which to attach
-    its LEFT OUTER JOIN.
-- mysql
-  - Nearly all MySQL column types are now supported for declaration
-    and reflection. Added NCHAR, NVARCHAR, VARBINARY, TINYBLOB,
-    LONGBLOB, YEAR
-  - The sqltypes.Binary passthrough now always builds a BLOB,
-    avoiding problems with very old database versions
-  - support for column-level CHARACTER SET and COLLATE declarations,
-    as well as ASCII, UNICODE, NATIONAL and BINARY shorthand.
-- firebird
-  - set max identifier length to 31
-  - supports_sane_rowcount() set to False due to ticket #370.
-    versioned_id_col feature wont work in FB.
-  - some execution fixes
--extensions
-  - new association proxy implementation, implementing complete
-    proxies to list, dict and set-based relation collections
-  - added orderinglist, a custom list class that synchronizes an
-    object attribute with that object's position in the list
-  - small fix to SelectResultsExt to not bypass itself during
-    select().
-  - added filter(), filter_by() to assignmapper
-
-0.3.7
-- engines
-    - warnings module used for issuing warnings (instead of logging)
-    - cleanup of DBAPI import strategies across all engines
-      [ticket:480]
-    - refactoring of engine internals which reduces complexity,
-      number of codepaths; places more state inside of ExecutionContext
-      to allow more dialect control of cursor handling, result sets.
-      ResultProxy totally refactored and also has two versions of
-      "buffered" result sets used for different purposes.
-    - server side cursor support fully functional in postgres
-      [ticket:514].
-    - improved framework for auto-invalidation of connections that have
-      lost their underlying database, via dialect-specific detection
-      of exceptions corresponding to that database's disconnect
-      related error messages.  Additionally, when a "connection no
-      longer open" condition is detected, the entire connection pool
-      is discarded and replaced with a new instance.  #516
-    - the dialects within sqlalchemy.databases become a setuptools
-      entry points. loading the built-in database dialects works the
-      same as always, but if none found will fall back to trying
-      pkg_resources to load an external module [ticket:521]
-    - Engine contains a "url" attribute referencing the url.URL object
-      used by create_engine().
-- sql:
-    - keys() of result set columns are not lowercased, come back
-      exactly as they're expressed in cursor.description.  note this
-      causes colnames to be all caps in oracle.
-    - preliminary support for unicode table names, column names and
-      SQL statements added, for databases which can support them.
-      Works with sqlite and postgres so far.  Mysql *mostly* works
-      except the has_table() function does not work.  Reflection
-      works too.
-    - the Unicode type is now a direct subclass of String, which now
-      contains all the "convert_unicode" logic.  This helps the variety
-      of unicode situations that occur in db's such as MS-SQL to be
-      better handled and allows subclassing of the Unicode datatype.
-      [ticket:522]
-    - ClauseElements can be used in in_() clauses now, such as bind
-      parameters, etc. #476
-    - reverse operators implemented for `CompareMixin` elements,
-      allows expressions like "5 + somecolumn" etc. #474
-    - the "where" criterion of an update() and delete() now correlates
-      embedded select() statements against the table being updated or
-      deleted.  this works the same as nested select() statement
-      correlation, and can be disabled via the correlate=False flag on
-      the embedded select().
-    - column labels are now generated in the compilation phase, which
-      means their lengths are dialect-dependent.  So on oracle a label
-      that gets truncated to 30 chars will go out to 63 characters
-      on postgres.  Also, the true labelname is always attached as the
-      accessor on the parent Selectable so theres no need to be aware
-      of the "truncated" label names [ticket:512].
-    - column label and bind param "truncation" also generate
-      deterministic names now, based on their ordering within the
-      full statement being compiled.  this means the same statement
-      will produce the same string across application restarts and
-      allowing DB query plan caching to work better.
-    - the "mini" column labels generated when using subqueries, which
-      are to work around glitchy SQLite behavior that doesnt understand
-      "foo.id" as equivalent to "id", are now only generated in the case
-      that those named columns are selected from (part of [ticket:513])
-    - the label() method on ColumnElement will properly propagate the
-      TypeEngine of the base element out to the label, including a label()
-      created from a scalar=True select() statement.
-    - MS-SQL better detects when a query is a subquery and knows not to
-      generate ORDER BY phrases for those [ticket:513]
-    - fix for fetchmany() "size" argument being positional in most
-      dbapis [ticket:505]
-    - sending None as an argument to func.<something> will produce
-      an argument of NULL
-    - query strings in unicode URLs get keys encoded to ascii
-      for **kwargs compat
-    - slight tweak to raw execute() change to also support tuples
-      for positional parameters, not just lists [ticket:523]
-    - fix to case() construct to propagate the type of the first
-      WHEN condition as the return type of the case statement
-- orm:
-    - fixed critical issue when, after options(eagerload()) is used,
-      the mapper would then always apply query "wrapping" behavior
-      for all subsequent LIMIT/OFFSET/DISTINCT queries, even if no
-      eager loading was applied on those subsequent queries.
-    - added query.with_parent(someinstance) method.  searches for
-      target instance using lazy join criterion from parent instance.
-      takes optional string "property" to isolate the desired relation.
-      also adds static Query.query_from_parent(instance, property)
-      version. [ticket:541]
-    - improved query.XXX_by(someprop=someinstance) querying to use
-      similar methodology to with_parent, i.e. using the "lazy" clause
-      which prevents adding the remote instance's table to the SQL,
-      thereby making more complex conditions possible [ticket:554]
-    - added generative versions of aggregates, i.e. sum(), avg(), etc.
-      to query. used via query.apply_max(), apply_sum(), etc.
-      #552
-    - fix to using distinct() or distinct=True in combination with
-      join() and similar
-    - corresponding to label/bindparam name generation, eager loaders
-      generate deterministic names for the aliases they create using
-      md5 hashes.
-    - improved/fixed custom collection classes when giving it "set"/
-      "sets.Set" classes or subclasses (was still looking for append()
-      methods on them during lazy loads)
-    - restored old "column_property()" ORM function (used to be called
-      "column()") to force any column expression to be added as a property
-      on a mapper, particularly those that aren't present in the mapped
-      selectable.  this allows "scalar expressions" of any kind to be
-      added as relations (though they have issues with eager loads).
-    - fix to many-to-many relationships targeting polymorphic mappers
-      [ticket:533]
-    - making progress with session.merge() as well as combining its
-      usage with entity_name [ticket:543]
-    - the usual adjustments to relationships between inheriting mappers,
-      in this case establishing relation()s to subclass mappers where
-      the join conditions come from the superclass' table
-- informix:
-    - informix support added !  courtesy James Zhang, who put a ton
-      of effort in.
-- sqlite:
-    - removed silly behavior where sqlite would reflect UNIQUE indexes
-      as part of the primary key (?!)
-- oracle:
-    - small fix to allow successive compiles of the same SELECT object
-      which features LIMIT/OFFSET.  oracle dialect needs to modify
-      the object to have ROW_NUMBER OVER and wasn't performing
-      the full series of steps on successive compiles.
-- mysql
-    - support for SSL arguments given as inline within URL query string,
-      prefixed with "ssl_", courtesy terjeros@gmail.com.
-    - mysql uses "DESCRIBE [<schemaname>].<tablename>", catching exceptions
-      if table doesnt exist, in order to determine if a table exists.
-      this supports unicode table names as well as schema names. tested
-      with MySQL5 but should work with 4.1 series as well. (#557)
-- extensions
-    - big fix to AssociationProxy so that multiple AssociationProxy
-      objects can be associated with a single association collection.
-    - assign_mapper names methods according to their keys (i.e. __name__)
-      #551
-- mssql
-    - pyodbc is now the preferred DB-API for MSSQL, and if no module is
-      specifically requested, will be loaded first on a module probe.
-
-    - The @@SCOPE_IDENTITY is now used instead of @@IDENTITY. This
-      behavior may be overridden with the engine_connect
-      "use_scope_identity" keyword parameter, which may also be specified
-      in the dburi.
-
-
-
-0.3.6
-- sql:
-    - bindparam() names are now repeatable!  specify two
-      distinct bindparam()s with the same name in a single statement,
-      and the key will be shared.  proper positional/named args translate
-      at compile time.  for the old behavior of "aliasing" bind parameters
-      with conflicting names, specify "unique=True" - this option is
-      still used internally for all the auto-genererated (value-based)
-      bind parameters.
-
-    - slightly better support for bind params as column clauses, either
-      via bindparam() or via literal(), i.e. select([literal('foo')])
-
-    - MetaData can bind to an engine either via "url" or "engine" kwargs
-      to constructor, or by using connect() method. BoundMetaData is
-      identical to MetaData except engine_or_url param is required.
-      DynamicMetaData is the same and provides thread-local connections be
-      default.
-
-    - exists() becomes useable as a standalone selectable, not just in a
-      WHERE clause, i.e. exists([columns], criterion).select()
-
-    - correlated subqueries work inside of ORDER BY, GROUP BY
-
-    - fixed function execution with explicit connections, i.e.
-      conn.execute(func.dosomething())
-
-    - use_labels flag on select() wont auto-create labels for literal text
-      column elements, since we can make no assumptions about the text. to
-      create labels for literal columns, you can say "somecol AS
-      somelabel", or use literal_column("somecol").label("somelabel")
-
-    - quoting wont occur for literal columns when they are "proxied" into
-      the column collection for their selectable (is_literal flag is
-      propagated). literal columns are specified via
-      literal_column("somestring").
-
-    - added "fold_equivalents" boolean argument to Join.select(), which
-      removes 'duplicate' columns from the resulting column clause that
-      are known to be equivalent based on the join condition. this is of
-      great usage when constructing subqueries of joins which Postgres
-      complains about if duplicate column names are present.
-
-    - fixed use_alter flag on ForeignKeyConstraint [ticket:503]
-
-    - fixed usage of 2.4-only "reversed" in topological.py [ticket:506]
-
-    - for hackers, refactored the "visitor" system of ClauseElement and
-      SchemaItem so that the traversal of items is controlled by the
-      ClauseVisitor itself, using the method visitor.traverse(item).
-      accept_visitor() methods can still be called directly but will not
-      do any traversal of child items. ClauseElement/SchemaItem now have a
-      configurable get_children() method to return the collection of child
-      elements for each parent object. This allows the full traversal of
-      items to be clear and unambiguous (as well as loggable), with an
-      easy method of limiting a traversal (just pass flags which are
-      picked up by appropriate get_children() methods). [ticket:501]
-
-    - the "else_" parameter to the case statement now properly works when
-      set to zero.
-
-- orm:
-    - the full featureset of the SelectResults extension has been merged
-      into a new set of methods available off of Query.  These methods
-      all provide "generative" behavior, whereby the Query is copied
-      and a new one returned with additional criterion added.
-      The new methods include:
-
-          filter() - applies select criterion to the query
-          filter_by() - applies "by"-style criterion to the query
-          avg() - return the avg() function on the given column
-          join() - join to a property (or across a list of properties)
-          outerjoin() - like join() but uses LEFT OUTER JOIN
-          limit()/offset() - apply LIMIT/OFFSET
-          range-based access which applies limit/offset:
-             session.query(Foo)[3:5]
-          distinct() - apply DISTINCT
-          list() - evaluate the criterion and return results
-
-      no incompatible changes have been made to Query's API and no methods
-      have been deprecated.  Existing methods like select(), select_by(),
-      get(), get_by() all execute the query at once and return results
-      like they always did.  join_to()/join_via() are still there although
-      the generative join()/outerjoin() methods are easier to use.
-
-    - the return value for multiple mappers used with instances() now
-      returns a cartesian product of the requested list of mappers,
-      represented as a list of tuples. this corresponds to the documented
-      behavior. So that instances match up properly, the "uniquing" is
-      disabled when this feature is used.
-
-    - Query has add_entity() and add_column() generative methods. these
-      will add the given mapper/class or ColumnElement to the query at
-      compile time, and apply them to the instances() method. the user is
-      responsible for constructing reasonable join conditions (otherwise
-      you can get full cartesian products). result set is the list of
-      tuples, non-uniqued.
-
-    - strings and columns can also be sent to the *args of instances()
-      where those exact result columns will be part of the result tuples.
-
-    - a full select() construct can be passed to query.select() (which
-      worked anyway), but also query.selectfirst(), query.selectone()
-      which will be used as is (i.e. no query is compiled). works
-      similarly to sending the results to instances().
-
-    - eager loading will not "aliasize" "order by" clauses that were
-      placed in the select statement by something other than the eager
-      loader itself, to fix possibility of dupe columns as illustrated in
-      [ticket:495]. however, this means you have to be more careful with
-      the columns placed in the "order by" of Query.select(), that you
-      have explicitly named them in your criterion (i.e. you cant rely on
-      the eager loader adding them in for you)
-
-    - added a handy multi-use "identity_key()" method to Session, allowing
-      the generation of identity keys for primary key values, instances,
-      and rows, courtesy Daniel Miller
-
-    - many-to-many table will be properly handled even for operations that
-      occur on the "backref" side of the operation [ticket:249]
-
-    - added "refresh-expire" cascade [ticket:492].  allows refresh() and
-      expire() calls to propagate along relationships.
-
-    - more fixes to polymorphic relations, involving proper lazy-clause
-      generation on many-to-one relationships to polymorphic mappers
-      [ticket:493]. also fixes to detection of "direction", more specific
-      targeting of columns that belong to the polymorphic union vs. those
-      that dont.
-
-    - some fixes to relationship calcs when using "viewonly=True" to pull
-      in other tables into the join condition which arent parent of the
-      relationship's parent/child mappings
-
-    - flush fixes on cyclical-referential relationships that contain
-      references to other instances outside of the cyclical chain, when
-      some of the objects in the cycle are not actually part of the flush
-
-    - put an aggressive check for "flushing object A with a collection of
-      B's, but you put a C in the collection" error condition - **even if
-      C is a subclass of B**, unless B's mapper loads polymorphically.
-      Otherwise, the collection will later load a "B" which should be a
-      "C" (since its not polymorphic) which breaks in bi-directional
-      relationships (i.e. C has its A, but A's backref will lazyload it as
-      a different instance of type "B") [ticket:500] This check is going
-      to bite some of you who do this without issues, so the error message
-      will also document a flag "enable_typechecks=False" to disable this
-      checking. But be aware that bi-directional relationships in
-      particular become fragile without this check.
-
-- extensions:
-    - options() method on SelectResults now implemented "generatively"
-      like the rest of the SelectResults methods [ticket:472].  But
-      you're going to just use Query now anyway.
-
-    - query() method is added by assignmapper.  this helps with
-      navigating to all the new generative methods on Query.
-
-- ms-sql:
-    - removed seconds input on DATE column types (probably
-        should remove the time altogether)
-
-    - null values in float fields no longer raise errors
-
-    - LIMIT with OFFSET now raises an error (MS-SQL has no OFFSET support)
-
-    - added an facility to use the MSSQL type VARCHAR(max) instead of TEXT
-      for large unsized string fields. Use the new "text_as_varchar" to
-      turn it on. [ticket:509]
-
-    - ORDER BY clauses without a LIMIT are now stripped in subqueries, as
-      MS-SQL forbids this usage
-
-    - cleanup of module importing code; specifiable DB-API module; more
-      explicit ordering of module preferences. [ticket:480]
-
-- oracle:
-    - got binary working for any size input !  cx_oracle works fine,
-      it was my fault as BINARY was being passed and not BLOB for
-      setinputsizes (also unit tests werent even setting input sizes).
-
-    - also fixed CLOB read/write on a separate changeset.
-
-    - auto_setinputsizes defaults to True for Oracle, fixed cases where
-      it improperly propagated bad types.
-
-- mysql:
-    - added a catchall **kwargs to MSString, to help reflection of
-      obscure types (like "varchar() binary" in MS 4.0)
-
-    - added explicit MSTimeStamp type which takes effect when using
-      types.TIMESTAMP.
-
-
-0.3.5
-- sql:
-    - the value of "case_sensitive" defaults to True now, regardless of the
-      casing of the identifier, unless specifically set to False. this is
-      because the object might be label'ed as something else which does
-      contain mixed case, and propigating "case_sensitive=False" breaks that.
-      Other fixes to quoting when using labels and "fake" column objects
-    - added a "supports_execution()" method to ClauseElement, so that
-      individual kinds of clauses can express if they are appropriate for
-      executing...such as, you can execute a "select", but not a "Table" or a
-      "Join".
-    - fixed argument passing to straight textual execute() on engine,
-      connection. can handle *args or a list instance for positional, **kwargs
-      or a dict instance for named args, or a list of list or dicts to invoke
-      executemany()
-    - small fix to BoundMetaData to accept unicode or string URLs
-    - fixed named PrimaryKeyConstraint generation [ticket:466] courtesy
-      andrija at gmail
-    - fixed generation of CHECK constraints on columns [ticket:464]
-    - fixes to tometadata() operation to propagate Constraints at column and
-      table level
-- oracle:
-    - when returning "rowid" as the ORDER BY column or in use with ROW_NUMBER
-      OVER, oracle dialect checks the selectable its being applied to and will
-      switch to table PK if not applicable, i.e. for a UNION. checking for
-      DISTINCT, GROUP BY (other places that rowid is invalid) still a TODO.
-      allows polymorphic mappings to function, [ticket:436]
-    - sequences on a non-pk column will properly fire off on INSERT
-    - added PrefetchingResultProxy support to pre-fetch LOB columns when they
-      are known to be present, fixes [ticket:435]
-    - implemented reflection of tables based on synonyms, including across
-      dblinks [ticket:379]
-    - issues a log warning when a related table cant be reflected due to
-      certain permission errors [ticket:363]
-- mysql:
-    - fix to reflection on older DB's that might return array() type for
-    "show variables like" statements
-- postgres:
-    - better reflection of sequences for alternate-schema Tables [ticket:442]
-    - sequences on a non-pk column will properly fire off on INSERT
-    - added PGInterval type [ticket:460], PGInet type [ticket:444]
-- mssql:
-    - preliminary support for pyodbc (Yay!) [ticket:419]
-    - better support for NVARCHAR types added [ticket:298]
-    - fix for commit logic on pymssql
-    - fix for query.get() with schema [ticket:456]
-    - fix for non-integer relationships [ticket:473]
-    - DB-API module now selectable at run-time [ticket:419]
-    - now passes many more unit tests [tickets:422, 481, 415]
-    - better unittest compatibility with ANSI functions [ticket:479]
-    - improved support for implicit sequence PK columns with auto-insert
-      [ticket:415]
-    - fix for blank password in adodbapi [ticket:371]
-    - fixes to get unit tests working with pyodbc [ticket:481]
-    - fix to auto_identity_insert on db-url query
-    - added query_timeout to db-url query parms. currently works only for
-      pymssql
-    - tested with pymssql 0.8.0 (which is now LGPL)
-- orm bugs:
-    - another refactoring to relationship calculation. Allows more accurate
-      ORM behavior with relationships from/to/between mappers, particularly
-      polymorphic mappers, also their usage with Query, SelectResults. tickets
-      include [ticket:439], [ticket:441], [ticket:448].
-    - removed deprecated method of specifying custom collections on classes;
-      you must now use the "collection_class" option. the old way was
-      beginning to produce conflicts when people used assign_mapper(), which
-      now patches an "options" method, in conjunction with a relationship
-      named "options". (relationships take precedence over monkeypatched
-      assign_mapper methods).
-    - extension() query option propagates to Mapper._instance() method so that
-      all loading-related methods get called [ticket:454]
-    - eager relation to an inheriting mapper wont fail if no rows returned for
-      the relationship.
-    - eager relation loading bug fixed for eager relation on multiple
-      descendant classes [ticket:486]
-    - fix for very large topological sorts, courtesy ants.aasma at gmail
-      [ticket:423]
-    - eager loading is slightly more strict about detecting "self-referential"
-      relationships, specifically between polymorphic mappers. this results in
-      an "eager degrade" to lazy loading.
-    - improved support for complex queries embedded into "where" criterion for
-      query.select() [ticket:449]
-    - mapper options like eagerload(), lazyload(), deferred(), will work for
-      "synonym()" relationships [ticket:485]
-    - fixed bug where cascade operations incorrectly included deleted
-      collection items in the cascade [ticket:445]
-    - fixed relationship deletion error when one-to-many child item is moved
-      to a new parent in a single unit of work [ticket:478]
-    - fixed relationship deletion error where parent/child with a single
-      column as PK/FK on the child would raise a "blank out the primary key"
-      error, if manually deleted or "delete" cascade without "delete-orphan"
-      was used
-    - fix to deferred so that load operation doesnt mistakenly occur when only
-      PK col attributes are set
-- orm enhancements:
-    - implemented foreign_keys argument to mapper [ticket:385]. use in
-      conjunction with primaryjoin/secondaryjoin arguments to specify/override
-      foreign keys defined on the Table instance.
-    - contains_eager('foo') automatically implies eagerload('foo')
-    - added "alias" argument to contains_eager(). use it to specify the string
-      name or Alias instance of an alias used in the query for the eagerly
-      loaded child items. easier to use than "decorator"
-    - added "contains_alias()" option for result set mapping to an alias of
-      the mapped table
-    - added support for py2.5 "with" statement with SessionTransaction
-      [ticket:468]
-- extensions:
-    - added distinct() method to SelectResults. generally should only make a
-      difference when using count().
-    - added options() method to SelectResults, equivalent to query.options()
-      [ticket:472]
-    - added optional __table_opts__ dictionary to ActiveMapper, will send kw
-      options to Table objects [ticket:462]
-    - added selectfirst(), selectfirst_by() to assign_mapper [ticket:467]
-
-0.3.4
-- general:
-  - global "insure"->"ensure" change. in US english "insure" is actually
-    largely interchangeable with "ensure" (so says the dictionary), so I'm not
-    completely illiterate, but its definitely sub-optimal to "ensure" which is
-    non-ambiguous.
-- sql:
-  - added "fetchmany()" support to ResultProxy
-  - added support for column "key" attribute to be useable in
-    row[<key>]/row.<key>
-  - changed "BooleanExpression" to subclass from "BinaryExpression", so that
-    boolean expressions can also follow column-clause behaviors (i.e. label(),
-    etc).
-  - trailing underscores are trimmed from func.<xxx> calls, such as func.if_()
-  - fix to correlation of subqueries when the column list of the select
-    statement is constructed with individual calls to append_column(); this
-    fixes an ORM bug whereby nested select statements were not getting
-    correlated with the main select generated by the Query object.
-  - another fix to subquery correlation so that a subquery which has only one
-    FROM element will *not* correlate that single element, since at least one
-    FROM element is required in a query.
-  - default "timezone" setting is now False. this corresponds to Python's
-    datetime behavior as well as Postgres' timestamp/time types (which is the
-    only timezone-sensitive dialect at the moment) [ticket:414]
-  - the "op()" function is now treated as an "operation", rather than a
-    "comparison". the difference is, an operation produces a BinaryExpression
-    from which further operations can occur whereas comparison produces the
-    more restrictive BooleanExpression
-  - trying to redefine a reflected primary key column as non-primary key raises
-    an error
-  - type system slightly modified to support TypeDecorators that can be
-    overridden by the dialect (ok, thats not very clear, it allows the mssql
-    tweak below to be possible)
-- mssql:
-  - added an NVarchar type (produces NVARCHAR), also MSUnicode which provides
-    Unicode-translation for the NVarchar regardless of dialect convert_unicode
-    setting.
-- postgres:
-  - fix to the initial checkfirst for tables to take current schema into
-    account [ticket:424]
-  - postgres has an optional "server_side_cursors=True" flag which will utilize
-    server side cursors. these are appropriate for fetching only partial
-    results and are necessary for working with very large unbounded result
-    sets. While we'd like this to be the default behavior, different
-    environments seem to have different results and the causes have not been
-    isolated so we are leaving the feature off by default for now. Uses an
-    apparently undocumented psycopg2 behavior recently discovered on the
-    psycopg mailing list.
-  - added "BIGSERIAL" support for postgres table with
-    PGBigInteger/autoincrement
-  - fixes to postgres reflection to better handle when schema names are
-    present; thanks to jason (at) ncsmags.com [ticket:402]
-- mysql:
-  - mysql is inconsistent with what kinds of quotes it uses in foreign keys
-    during a SHOW CREATE TABLE, reflection updated to accomodate for all three
-    styles [ticket:420]
-  - mysql table create options work on a generic passthru now, i.e. Table(...,
-    mysql_engine='InnoDB', mysql_collate="latin1_german2_ci",
-    mysql_auto_increment="5", mysql_<somearg>...), helps [ticket:418]
-- firebird:
-  - order of constraint creation puts primary key first before all other
-    constraints; required for firebird, not a bad idea for others [ticket:408]
-  - Firebird fix to autoload multifield foreign keys [ticket:409]
-  - Firebird NUMERIC type properly handles a type without precision
-    [ticket:409]
-- oracle:
-  - *slight* support for binary, but still need to figure out how to insert
-    reasonably large values (over 4K). requires auto_setinputsizes=True sent to
-    create_engine(), rows must be fully fetched individually, etc.
-- orm:
-  - poked the first hole in the can of worms: saying
-    query.select_by(somerelationname=someinstance) will create the join of the
-    primary key columns represented by "somerelationname"'s mapper to the
-    actual primary key in "someinstance".
-  - reworked how relations interact with "polymorphic" mappers, i.e. mappers
-    that have a select_table as well as polymorphic flags. better determination
-    of proper join conditions, interaction with user- defined join conditions,
-    and support for self-referential polymorphic mappers.
-  - related to polymorphic mapping relations, some deeper error checking when
-    compiling relations, to detect an ambiguous "primaryjoin" in the case that
-    both sides of the relationship have foreign key references in the primary
-    join condition. also tightened down conditions used to locate "relation
-    direction", associating the "foreignkey" of the relationship with the
-    "primaryjoin"
-  - a little bit of improvement to the concept of a "concrete" inheritance
-    mapping, though that concept is not well fleshed out yet (added test case
-    to support concrete mappers on top of a polymorphic base).
-  - fix to "proxy=True" behavior on synonym()
-  - fixed bug where delete-orphan basically didn't work with many-to-many
-    relationships [ticket:427], backref presence generally hid the symptom
-  - added a mutex to the mapper compilation step. ive been reluctant to add any
-    kind of threading anything to SA but this is one spot that its its really
-    needed since mappers are typically "global", and while their state does not
-    change during normal operation, the initial compilation step does modify
-    internal state significantly, and this step usually occurs not at
-    module-level initialization time (unless you call compile()) but at
-    first-request time
-  - basic idea of "session.merge()" actually implemented.  needs more testing.
-  - added "compile_mappers()" function as a shortcut to compiling all mappers
-  - fix to MapperExtension create_instance so that entity_name properly
-    associated with new instance
-  - speed enhancements to ORM object instantiation, eager loading of rows
-  - invalid options sent to 'cascade' string will raise an exception
-    [ticket:406]
-  - fixed bug in mapper refresh/expire whereby eager loaders didnt properly
-    re-populate item lists [ticket:407]
-  - fix to post_update to ensure rows are updated even for non insert/delete
-    scenarios [ticket:413]
-  - added an error message if you actually try to modify primary key values on
-    an entity and then flush it [ticket:412]
-- extensions
-  - added "validate=False" argument to assign_mapper, if True will ensure that
-    only mapped attributes are named [ticket:426]
-  - assign_mapper gets "options", "instances" functions added (i.e.
-    MyClass.instances())
-
-0.3.3
-- string-based FROM clauses fixed, i.e. select(..., from_obj=["sometext"])
-- fixes to passive_deletes flag, lazy=None (noload) flag
-- added example/docs for dealing with large collections
-- added object_session() method to sqlalchemy namespace
-- fixed QueuePool bug whereby its better able to reconnect to a database
-that was not reachable (thanks to Sébastien Lelong), also fixed dispose()
-method
-- patch that makes MySQL rowcount work correctly! [ticket:396]
-- fix to MySQL catch of 2006/2014 errors to properly re-raise OperationalError
-exception
-
-0.3.2
-- major connection pool bug fixed.  fixes MySQL out of sync
-errors, will also prevent transactions getting rolled back
-accidentally in all DBs [ticket:387]
-- major speed enhancements vs. 0.3.1, to bring speed
-back to 0.2.8 levels
-  - made conditional dozens of debug log calls that were
-  time-intensive to generate log messages
-  - fixed bug in cascade rules whereby the entire object graph
-  could be unnecessarily cascaded on the save/update cascade
-  - various speedups in attributes module
-- identity map in Session is by default *no longer weak referencing*.
-to have it be weak referencing, use create_session(weak_identity_map=True)
-fixes [ticket:388]
-- MySQL detects errors 2006 (server has gone away) and 2014
-(commands out of sync) and invalidates the connection on which it occured.
-- MySQL bool type fix: [ticket:307]
-- postgres reflection fixes: [ticket:349] [ticket:382]
-- added keywords for EXCEPT, INTERSECT, EXCEPT ALL, INTERSECT ALL
-[ticket:247]
-- assign_mapper in assignmapper extension returns the created mapper
-[changeset:2110]
-- added label() function to Select class, when scalar=True is used
-to create a scalar subquery
-i.e. "select x, y, (select max(foo) from table) AS foomax from table"
-- added onupdate and ondelete keyword arguments to ForeignKey; propagate
-to underlying ForeignKeyConstraint if present.  (dont propagate in the
-other direction, however)
-- fix to session.update() to preserve "dirty" status of incoming object
-- sending a selectable to an IN via the in_() function no longer creates
-a "union" out of multiple selects; only one selectable to a the in_() function
-is allowed now (make a union yourself if union is needed)
-- improved support for disabling save-update cascade via cascade="none" etc.
-- added "remote_side" argument to relation(), used only with self-referential
-mappers to force the direction of the parent/child relationship.  replaces
-the usage of the "foreignkey" parameter for "switching" the direction.
-"foreignkey" argument is deprecated for all uses and will eventually
-be replaced by an argument dedicated to ForeignKey specification on mappers.
-
-0.3.1
-- Engine/Pool:
-  - some new Pool utility classes, updated docs
-  - "use_threadlocal" on Pool defaults to False (same as create_engine)
-  - fixed direct execution of Compiled objects
-  - create_engine() reworked to be strict about incoming **kwargs.  all keyword
-arguments must be consumed by one of the dialect, connection pool, and engine
-constructors, else a TypeError is thrown which describes the full set of
-invalid kwargs in relation to the selected dialect/pool/engine configuration.
-- Databases/Types:
-  - MySQL catches exception on "describe" and reports as NoSuchTableError
-  - further fixes to sqlite booleans, weren't working as defaults
-  - fix to postgres sequence quoting when using schemas
-- ORM:
-  - the "delete" cascade will load in all child objects, if they were not
-loaded already.  this can be turned off (i.e. the old behavior) by setting
-passive_deletes=True on a relation().
-  - adjustments to reworked eager query generation to not fail on circular
-eager-loaded relationships (like backrefs)
-  - fixed bug where eagerload() (nor lazyload()) option didn't properly
-instruct the Query whether or not to use "nesting" when producing a
-LIMIT query.
-  - fixed bug in circular dependency sorting at flush time; if object A
-contained a cyclical many-to-one relationship to object B, and object B
-was just attached to object A, *but* object B itself wasnt changed,
-the many-to-one synchronize of B's primary key attribute to A's foreign key
-attribute wouldnt occur.  [ticket:360]
-  - implemented from_obj argument for query.count, improves count function
-on selectresults [ticket:325]
-  - added an assertion within the "cascade" step of ORM relationships to check
-that the class of object attached to a parent object is appropriate
-(i.e. if A.items stores B objects, raise an error if a C is appended to A.items)
-  - new extension sqlalchemy.ext.associationproxy, provides transparent
-"association object" mappings.  new example
-examples/association/proxied_association.py illustrates.
-  - improvement to single table inheritance to load full hierarchies beneath
-the target class
-  - fix to subtle condition in topological sort where a node could appear twice,
-for [ticket:362]
-  - additional rework to topological sort, refactoring, for [ticket:365]
-  - "delete-orphan" for a certain type can be set on more than one parent class;
-the instance is an "orphan" only if its not attached to *any* of those parents
-
-0.3.0
-- General:
-    - logging is now implemented via standard python "logging" module.
-    "echo" keyword parameters are still functional but set/unset
-    log levels for their respective classes/instances.  all logging
-    can be controlled directly through the Python API by setting
-    INFO and DEBUG levels for loggers in the "sqlalchemy" namespace.
-    class-level logging is under "sqlalchemy.<module>.<classname>",
-    instance-level logging under "sqlalchemy.<module>.<classname>.0x..<00-FF>".
-    Test suite includes "--log-info" and "--log-debug" arguments
-    which work independently of --verbose/--quiet.  Logging added
-    to orm to allow tracking of mapper configurations, row iteration.
-    - the documentation-generation system has been overhauled to be
-    much simpler in design and more integrated with Markdown
-- Specific Databases:
-    - SQLite:
-    - sqlite boolean datatype converts False/True to 0/1 by default
-    - fixes to Date/Time (SLDate/SLTime) types; works as good as postgres
-    now [ticket:335]
-    - MS-SQL:
-    - fixes bug 261 (table reflection broken for MS-SQL case-sensitive
-    databases)
-    - can now specify port for pymssql
-    - introduces new "auto_identity_insert" option for auto-switching
-    between "SET IDENTITY_INSERT" mode when values specified for IDENTITY columns
-    - now supports multi-column foreign keys
-    - fix to reflecting date/datetime columns
-    - NCHAR and NVARCHAR type support added
-    - Oracle:
-    - Oracle has experimental support for cx_Oracle.TIMESTAMP, which requires
-    a setinputsizes() call on the cursor that is now enabled via the
-    'auto_setinputsizes' flag to the oracle dialect.
-    - Firebird:
-    - aliases do not use "AS"
-    - correctly raises NoSuchTableError when reflecting non-existent table
-- Schema:
-    - a fair amount of cleanup to the schema package, removal of ambiguous
-    methods, methods that are no longer needed.  slightly more constrained
-    useage, greater emphasis on explicitness
-    - the "primary_key" attribute of Table and other selectables becomes
-    a setlike ColumnCollection object; is ordered but not numerically
-    indexed.  a comparison clause between two pks that are derived from the
-    same underlying tables (i.e. such as two Alias objects) can be generated
-    via table1.primary_key==table2.primary_key
-    - ForeignKey(Constraint) supports "use_alter=True", to create/drop a foreign key
-    via ALTER.  this allows circular foreign key relationships to be set up.
-    - append_item() methods removed from Table and Column; preferably
-    construct Table/Column/related objects inline, but if needed use
-    append_column(), append_foreign_key(), append_constraint(), etc.
-    - table.create() no longer returns the Table object, instead has no
-    return value.  the usual case is that tables are created via metadata,
-    which is preferable since it will handle table dependencies.
-    - added UniqueConstraint (goes at Table level), CheckConstraint
-    (goes at Table or Column level).
-    - index=False/unique=True on Column now creates a UniqueConstraint,
-    index=True/unique=False creates a plain Index,
-    index=True/unique=True on Column creates a unique Index.  'index'
-    and 'unique' keyword arguments to column are now boolean only; for
-    explcit names and groupings of indexes or unique constraints, use the
-    UniqueConstraint/Index constructs explicitly.
-    - added autoincrement=True to Column; will disable schema generation
-    of SERIAL/AUTO_INCREMENT/identity seq for postgres/mysql/mssql if
-    explicitly set to False
-    - TypeEngine objects now have methods to deal with copying and comparing
-    values of their specific type.  Currently used by the ORM, see below.
-    - fixed condition that occurred during reflection when a primary key
-    column was explciitly overridden, where the PrimaryKeyConstraint would
-    get both the reflected and the programmatic column doubled up
-    - the "foreign_key" attribute on Column and ColumnElement in general
-    is deprecated, in favor of the "foreign_keys" list/set-based attribute,
-    which takes into account multiple foreign keys on one column.
-    "foreign_key" will return the first element in the "foreign_keys" list/set
-    or None if the list is empty.
-- Connections/Pooling/Execution:
-    - connection pool tracks open cursors and automatically closes them
-    if connection is returned to pool with cursors still opened.  Can be
-    affected by options which cause it to raise an error instead, or to
-    do nothing.  fixes issues with MySQL, others
-    - fixed bug where Connection wouldnt lose its Transaction
-    after commit/rollback
-    - added scalar() method to ComposedSQLEngine, ResultProxy
-    - ResultProxy will close() the underlying cursor when the ResultProxy
-    itself is closed.  this will auto-close cursors for ResultProxy objects
-    that have had all their rows fetched (or had scalar() called).
-    - ResultProxy.fetchall() internally uses DBAPI fetchall() for better efficiency,
-    added to mapper iteration as well (courtesy Michael Twomey)
-- SQL Construction:
-    - changed "for_update" parameter to accept False/True/"nowait"
-    and "read", the latter two of which are interpreted only by
-    Oracle and Mysql [ticket:292]
-    - added extract() function to sql dialect
-    (SELECT extract(field FROM expr))
-    - BooleanExpression includes new "negate" argument to specify
-    the appropriate negation operator if one is available.
-    - calling a negation on an "IN" or "IS" clause will result in
-    "NOT IN", "IS NOT" (as opposed to NOT (x IN y)).
-    - Function objects know what to do in a FROM clause now.  their
-    behavior should be the same, except now you can also do things like
-    select(['*'], from_obj=[func.my_function()]) to get multiple
-    columns from the result, or even use sql.column() constructs to name the
-    return columns [ticket:172]
-- ORM:
-    - attribute tracking modified to be more intelligent about detecting
-    changes, particularly with mutable types.  TypeEngine objects now
-    take a greater role in defining how to compare two scalar instances,
-    including the addition of a MutableType mixin which is implemented by
-    PickleType.  unit-of-work now tracks the "dirty" list as an expression
-    of all persistent objects where the attribute manager detects changes.
-    The basic issue thats fixed is detecting changes on PickleType
-    objects, but also generalizes type handling and "modified" object
-    checking to be more complete and extensible.
-    - a wide refactoring to "attribute loader" and "options" architectures.
-    ColumnProperty and PropertyLoader define their loading behaivor via switchable
-    "strategies", and MapperOptions no longer use mapper/property copying
-    in order to function; they are instead propagated via QueryContext
-    and SelectionContext objects at query/instances time.
-    All of the internal copying of mappers and properties that was used to handle
-    inheritance as well as options() has been removed; the structure
-    of mappers and properties is much simpler than before and is clearly laid out
-    in the new 'interfaces' module.
-    - related to the mapper/property overhaul, internal refactoring to
-    mapper instances() method to use a SelectionContext object to track
-    state during the operation.
-    SLIGHT API BREAKAGE: the append_result() and populate_instances()
-    methods on MapperExtension have a slightly different method signature
-    now as a result of the change; hoping that these methods are not
-    in widespread use as of yet.
-    - instances() method moved to Query now, backwards-compatible
-    version remains on Mapper.
-    - added contains_eager() MapperOption, used in conjunction with
-    instances() to specify properties that should be eagerly loaded
-    from the result set, using their plain column names by default, or translated
-    given an custom row-translation function.
-    - more rearrangements of unit-of-work commit scheme to better allow
-    dependencies within circular flushes to work properly...updated
-    task traversal/logging implementation
-    - polymorphic mappers (i.e. using inheritance) now produces INSERT
-    statements in order of tables across all inherited classes
-    [ticket:321]
-    - added an automatic "row switch" feature to mapping, which will
-    detect a pending instance/deleted instance pair with the same
-    identity key and convert the INSERT/DELETE to a single UPDATE
-    - "association" mappings simplified to take advantage of
-    automatic "row switch" feature
-    - "custom list classes" is now implemented via the "collection_class"
-    keyword argument to relation().  the old way still works but is
-    deprecated [ticket:212]
-    - added "viewonly" flag to relation(), allows construction of
-    relations that have no effect on the flush() process.
-    - added "lockmode" argument to base Query select/get functions,
-    including "with_lockmode" function to get a Query copy that has
-    a default locking mode.  Will translate "read"/"update"
-    arguments into a for_update argument on the select side.
-    [ticket:292]
-    - implemented "version check" logic in Query/Mapper, used
-    when version_id_col is in effect and query.with_lockmode()
-    is used to get() an instance thats already loaded
-    - post_update behavior improved; does a better job at not
-    updating too many rows, updates only required columns
-    [ticket:208]
-    - adjustments to eager loading so that its "eager chain" is
-    kept separate from the normal mapper setup, thereby
-    preventing conflicts with lazy loader operation, fixes
-    [ticket:308]
-    - fix to deferred group loading
-    - session.flush() wont close a connection it opened [ticket:346]
-    - added "batch=True" flag to mapper; if False, save_obj
-    will fully save one object at a time including calls
-    to before_XXXX and after_XXXX
-    - added "column_prefix=None" argument to mapper; prepends the
-    given string (typically '_') to column-based attributes automatically
-    set up from the mapper's Table
-    - specifying joins in the from_obj argument of query.select() will
-    replace the main table of the query, if the table is somewhere within
-    the given from_obj.  this makes it possible to produce custom joins and
-    outerjoins in queries without the main table getting added twice.
-    [ticket:315]
-    - eagerloading is adjusted to more thoughtfully attach its LEFT OUTER JOINs
-    to the given query, looking for custom "FROM" clauses that may have
-    already been set up.
-    - added join_to and outerjoin_to transformative methods to SelectResults,
-    to build up join/outerjoin conditions based on property names. also
-    added select_from to explicitly set from_obj parameter.
-    - removed "is_primary" flag from mapper.
-
-0.2.8
-- cleanup on connection methods + documentation.  custom DBAPI
-arguments specified in query string, 'connect_args' argument
-to 'create_engine', or custom creation function via 'creator'
-function to 'create_engine'.
-- added "recycle" argument to Pool, is "pool_recycle" on create_engine,
-defaults to 3600 seconds; connections after this age will be closed and
-replaced with a new one, to handle db's that automatically close
-stale connections [ticket:274]
-- changed "invalidate" semantics with pooled connection; will
-instruct the underlying connection record to reconnect the next
-time its called.  "invalidate" will also automatically be called
-if any error is thrown in the underlying call to connection.cursor().
-this will hopefully allow the connection pool to reconnect to a
-database that had been stopped and started without restarting
-the connecting application [ticket:121]
-- eesh !  the tutorial doctest was broken for quite some time.
-- add_property() method on mapper does a "compile all mappers"
-step in case the given property references a non-compiled mapper
-(as it did in the case of the tutorial !)
-- [ticket:277] check for pg sequence already existing before create
-- if a contextual session is established via MapperExtension.get_session
-(as it is using the sessioncontext plugin, etc), a lazy load operation
-will use that session by default if the parent object is not
-persistent with a session already.
-- lazy loads will not fire off for an object that does not have a
-database identity (why?
-see http://www.sqlalchemy.org/trac/wiki/WhyDontForeignKeysLoadData)
-- unit-of-work does a better check for "orphaned" objects that are
-part of a "delete-orphan" cascade, for certain conditions where the
-parent isnt available to cascade from.
-- mappers can tell if one of their objects is an "orphan" based
-on interactions with the attribute package. this check is based
-on a status flag maintained for each relationship
-when objects are attached and detached from each other.
-- it is now invalid to declare a self-referential relationship with
-"delete-orphan" (as the abovementioned check would make them impossible
-to save)
-- improved the check for objects being part of a session when the
-unit of work seeks to flush() them as part of a relationship..
-- [ticket:280] statement execution supports using the same BindParam
-object more than once in an expression; simplified handling of positional
-parameters.  nice job by Bill Noon figuring out the basic idea.
-- postgres reflection moved to use pg_schema tables, can be overridden
-with use_information_schema=True argument to create_engine
-[ticket:60], [ticket:71]
-- added case_sensitive argument to MetaData, Table, Column, determines
-itself automatically based on if a parent schemaitem has a non-None
-setting for the flag, or if not, then whether the identifier name is all lower
-case or not.  when set to True, quoting is applied to identifiers with mixed or
-uppercase identifiers.  quoting is also applied automatically in all cases to
-identifiers that are known to be reserved words or contain other non-standard
-characters. various database dialects can override all of this behavior, but
-currently they are all using the default behavior.  tested with postgres, mysql,
-sqlite, oracle.  needs more testing with firebird, ms-sql. part of the ongoing
-work with [ticket:155]
-- unit tests updated to run without any pysqlite installed; pool
-test uses a mock DBAPI
-- urls support escaped characters in passwords [ticket:281]
-- added limit/offset to UNION queries (though not yet in oracle)
-- added "timezone=True" flag to DateTime and Time types.  postgres
-so far will convert this to "TIME[STAMP] (WITH|WITHOUT) TIME ZONE",
-so that control over timezone presence is more controllable (psycopg2
-returns datetimes with tzinfo's if available, which can create confusion
-against datetimes that dont).
-- fix to using query.count() with distinct, **kwargs with SelectResults
-count() [ticket:287]
-- deregister Table from MetaData when autoload fails; [ticket:289]
-- import of py2.5s sqlite3 [ticket:293]
-- unicode fix for startswith()/endswith() [ticket:296]
-
-0.2.7
-- quoting facilities set up so that database-specific quoting can be
-turned on for individual table, schema, and column identifiers when
-used in all queries/creates/drops.  Enabled via "quote=True" in
-Table or Column, as well as "quote_schema=True" in Table.  Thanks to
-Aaron Spike for his excellent efforts.
-- assignmapper was setting is_primary=True, causing all sorts of mayhem
-by not raising an error when redundant mappers were set up, fixed
-- added allow_null_pks option to Mapper, allows rows where some
-primary key columns are null (i.e. when mapping to outer joins etc)
-- modifcation to unitofwork to not maintain ordering within the
-"new" list or within the UOWTask "objects" list; instead, new objects
-are tagged with an ordering identifier as they are registered as new
-with the session, and the INSERT statements are then sorted within the
-mapper save_obj.  the INSERT ordering has basically been pushed all
-the way to the end of the flush cycle. that way the various sorts and
-organizations occuring within UOWTask (particularly the circular task
-sort) dont have to worry about maintaining order (which they werent anyway)
-- fixed reflection of foreign keys to autoload the referenced table
-if it was not loaded already
-- [ticket:256] - pass URL query string arguments to connect() function
-- [ticket:257] - oracle boolean type
-- custom primary/secondary join conditions in a relation *will* be propagated
-to backrefs by default.  specifying a backref() will override this behavior.
-- better check for ambiguous join conditions in sql.Join; propagates to a
-better error message in PropertyLoader (i.e. relation()/backref()) for when
-the join condition can't be reasonably determined.
-- sqlite creates ForeignKeyConstraint objects properly upon table
-reflection.
-- adjustments to pool stemming from changes made for [ticket:224].
-overflow counter should only be decremented if the connection actually
-succeeded.  added a test script to attempt testing this.
-- fixed mysql reflection of default values to be PassiveDefault
-- added reflected 'tinyint', 'mediumint' type to MS-SQL [ticket:263],
-[ticket:264]
-- SingletonThreadPool has a size and does a cleanup pass, so that
-only a given number of thread-local connections stay around (needed
-for sqlite applications that dispose of threads en masse)
-- fixed small pickle bug(s) with lazy loaders [ticket:265] [ticket:267]
-- fixed possible error in mysql reflection where certain versions
-return an array instead of string for SHOW CREATE TABLE call
-- fix to lazy loads when mapping to joins [changeset:1770]
-- all create()/drop() calls have a keyword argument of "connectable".
-"engine" is deprecated.
-- fixed ms-sql connect() to work with adodbapi
-- added "nowait" flag to Select()
-- inheritance check uses issubclass() instead of direct __mro__ check
-to make sure class A inherits from B, allowing mapper inheritance to more
-flexibly correspond to class inheritance [ticket:271]
-- SelectResults will use a subselect, when calling an aggregate (i.e.
-max, min, etc.) on a SelectResults that has an ORDER BY clause
-[ticket:252]
-- fixes to types so that database-specific types more easily used;
-fixes to mysql text types to work with this methodology
-[ticket:269]
-- some fixes to sqlite date type organization
-- added MSTinyInteger to MS-SQL [ticket:263]
-
-0.2.6
-- big overhaul to schema to allow truly composite primary and foreign
-key constraints, via new ForeignKeyConstraint and PrimaryKeyConstraint
-objects.
-Existing methods of primary/foreign key creation have not been changed
-but use these new objects behind the scenes.  table creation
-and reflection is now more table oriented rather than column oriented.
-[ticket:76]
-- overhaul to MapperExtension calling scheme, wasnt working very well
-previously
-- tweaks to ActiveMapper, supports self-referential relationships
-- slight rearrangement to objectstore (in activemapper/threadlocal)
-so that the SessionContext is referenced by '.context' instead
-of subclassed directly.
-- activemapper will use threadlocal's objectstore if the mod is
-activated when activemapper is imported
-- small fix to URL regexp to allow filenames with '@' in them
-- fixes to Session expunge/update/etc...needs more cleanup.
-- select_table mappers *still* werent always compiling
-- fixed up Boolean datatype
-- added count()/count_by() to list of methods proxied by assignmapper;
-this also adds them to activemapper
-- connection exceptions wrapped in DBAPIError
-- ActiveMapper now supports autoloading column definitions from the
-database if you supply a __autoload__ = True attribute in your
-mapping inner-class.  Currently this does not support reflecting
-any relationships.
-- deferred column load could screw up the connection status in
-a flush() under some circumstances, this was fixed
-- expunge() was not working with cascade, fixed.
-- potential endless loop in cascading operations fixed.
-- added "synonym()" function, applied to properties to have a
-propname the same as another, for the purposes of overriding props
-and allowing the original propname to be accessible in select_by().
-- fix to typing in clause construction which specifically helps
-type issues with polymorphic_union (CAST/ColumnClause propagates
-its type to proxy columns)
-- mapper compilation work ongoing, someday it'll work....moved
-around the initialization of MapperProperty objects to be after
-all mappers are created to better handle circular compilations.
-do_init() method is called on all properties now which are more
-aware of their "inherited" status if so.
-- eager loads explicitly disallowed on self-referential relationships, or
-relationships to an inheriting mapper (which is also self-referential)
-- reduced bind param size in query._get to appease the picky oracle
-[ticket:244]
-- added 'checkfirst' argument to table.create()/table.drop(), as
-well as table.exists() [ticket:234]
-- some other ongoing fixes to inheritance [ticket:245]
-- attribute/backref/orphan/history-tracking tweaks as usual...
-
-0.2.5
-- fixed endless loop bug in select_by(), if the traversal hit
-two mappers that referenced each other
-- upgraded all unittests to insert './lib/' into sys.path,
-working around new setuptools PYTHONPATH-killing behavior
-- further fixes with attributes/dependencies/etc....
-- improved error handling for when DynamicMetaData is not connected
-- MS-SQL support largely working (tested with pymssql)
-- ordering of UPDATE and DELETE statements within groups is now
-in order of primary key values, for more deterministic ordering
-- after_insert/delete/update mapper extensions now called per object,
-not per-object-per-table
-- further fixes/refactorings to mapper compilation
-
-0.2.4
-- try/except when the mapper sets init.__name__ on a mapped class,
-supports python 2.3
-- fixed bug where threadlocal engine would still autocommit
-despite a transaction in progress
-- lazy load and deferred load operations require the parent object
-to be in a Session to do the operation; whereas before the operation
-would just return a blank list or None, it now raises an exception.
-- Session.update() is slightly more lenient if the session to which
-the given object was formerly attached to was garbage collected;
-otherwise still requires you explicitly remove the instance from
-the previous Session.
-- fixes to mapper compilation, checking for more error conditions
-- small fix to eager loading combined with ordering/limit/offset
-- utterly remarkable:  added a single space between 'CREATE TABLE'
-and '(<the rest of it>' since *thats how MySQL indicates a non-
-reserved word tablename.....* [ticket:206]
-- more fixes to inheritance, related to many-to-many relations
-properly saving
-- fixed bug when specifying explicit module to mysql dialect
-- when QueuePool times out it raises a TimeoutError instead of
-erroneously making another connection
-- Queue.Queue usage in pool has been replaced with a locally
-modified version (works in py2.3/2.4!) that uses a threading.RLock
-for a mutex.  this is to fix a reported case where a ConnectionFairy's
-__del__() method got called within the Queue's get() method, which
-then returns its connection to the Queue via the the put() method,
-causing a reentrant hang unless threading.RLock is used.
-- postgres will not place SERIAL keyword on a primary key column
-if it has a foreign key constraint
-- cursor() method on ConnectionFairy allows db-specific extension
-arguments to be propagated [ticket:221]
-- lazy load bind params properly propagate column type [ticket:225]
-- new MySQL types: MSEnum, MSTinyText, MSMediumText, MSLongText, etc.
-more support for MS-specific length/precision params in numeric types
-patch courtesy Mike Bernson
-- some fixes to connection pool invalidate() [ticket:224]
-
-0.2.3
-- overhaul to mapper compilation to be deferred.  this allows mappers
-to be constructed in any order, and their relationships to each
-other are compiled when the mappers are first used.
-- fixed a pretty big speed bottleneck in cascading behavior particularly
-when backrefs were in use
-- the attribute instrumentation module has been completely rewritten; its
-now a large degree simpler and clearer, slightly faster.  the "history"
-of an attribute is no longer micromanaged with each change and is
-instead part of a "CommittedState" object created when the
-instance is first loaded.  HistoryArraySet is gone, the behavior of
-list attributes is now more open ended (i.e. theyre not sets anymore).
-- py2.4 "set" construct used internally, falls back to sets.Set when
-"set" not available/ordering is needed.
-- fix to transaction control, so that repeated rollback() calls
-dont fail (was failing pretty badly when flush() would raise
-an exception in a larger try/except transaction block)
-- "foreignkey" argument to relation() can also be a list.  fixed
-auto-foreignkey detection [ticket:151]
-- fixed bug where tables with schema names werent getting indexed in
-the MetaData object properly
-- fixed bug where Column with redefined "key" property wasnt getting
-type conversion happening in the ResultProxy [ticket:207]
-- fixed 'port' attribute of URL to be an integer if present
-- fixed old bug where if a many-to-many table mapped as "secondary"
-had extra columns, delete operations didnt work
-- bugfixes for mapping against UNION queries
-- fixed incorrect exception class thrown when no DB driver present
-- added NonExistentTable exception thrown when reflecting a table
-that doesnt exist [ticket:138]
-- small fix to ActiveMapper regarding one-to-one backrefs, other
-refactorings
-- overridden constructor in mapped classes gets __name__ and
-__doc__ from the original class
-- fixed small bug in selectresult.py regarding mapper extension
-[ticket:200]
-- small tweak to cascade_mappers, not very strongly supported
-function at the moment
-- some fixes to between(), column.between() to propagate typing
-information better [ticket:202]
-- if an object fails to be constructed, is not added to the
-session [ticket:203]
-- CAST function has been made into its own clause object with
-its own compilation function in ansicompiler; allows MySQL
-to silently ignore most CAST calls since MySQL
-seems to only support the standard CAST syntax with Date types.
-MySQL-compatible CAST support for strings, ints, etc. a TODO
-
-0.2.2
-- big improvements to polymorphic inheritance behavior, enabling it
-to work with adjacency list table structures [ticket:190]
-- major fixes and refactorings to inheritance relationships overall,
-more unit tests
-- fixed "echo_pool" flag on create_engine()
-- fix to docs, removed incorrect info that close() is unsafe to use
-with threadlocal strategy (its totally safe !)
-- create_engine() can take URLs as string or unicode [ticket:188]
-- firebird support partially completed;
-thanks to James Ralston and Brad Clements for their efforts.
-- Oracle url translation was broken, fixed, will feed host/port/sid
-into cx_oracle makedsn() if 'database' field is present, else uses
-straight TNS name from the 'host' field
-- fix to using unicode criterion for query.get()/query.load()
-- count() function on selectables now uses table primary key or
-first column instead of "1" for criterion, also uses label "rowcount"
-instead of "count".
-- got rudimental "mapping to multiple tables" functionality cleaned up,
-more correctly documented
-- restored global_connect() function, attaches to a DynamicMetaData
-instance called "default_metadata".  leaving MetaData arg to Table
-out will use the default metadata.
-- fixes to session cascade behavior, entity_name propigation
-- reorganized unittests into subdirectories
-- more fixes to threadlocal connection nesting patterns
-
-0.2.1
-- "pool" argument to create_engine() properly propagates
-- fixes to URL, raises exception if not parsed, does not pass blank
-fields along to the DB connect string (a string such as
-user:host@/db was breaking on postgres)
-- small fixes to Mapper when it inserts and tries to get
-new primary key values back
-- rewrote half of TLEngine, the ComposedSQLEngine used with
-'strategy="threadlocal"'.  it now properly implements engine.begin()/
-engine.commit(), which nest fully with connection.begin()/trans.commit().
-added about six unittests.
-- major "duh" in pool.Pool, forgot to put back the WeakValueDictionary.
-unittest which was supposed to check for this was also silently missing
-it.  fixed unittest to ensure that ConnectionFairy properly falls out
-of scope.
-- placeholder dispose() method added to SingletonThreadPool, doesnt
-do anything yet
-- rollback() is automatically called when an exception is raised,
-but only if theres no transaction in process (i.e. works more like
-autocommit).
-- fixed exception raise in sqlite if no sqlite module present
-- added extra example detail for association object doc
-- Connection adds checks for already being closed
-
-0.2.0
-- overhaul to Engine system so that what was formerly the SQLEngine
-is now a ComposedSQLEngine which consists of a variety of components,
-including a Dialect, ConnectionProvider, etc. This impacted all the
-db modules as well as Session and Mapper.
-- create_engine now takes only RFC-1738-style strings:
-driver://user:password@host:port/database
-- total rewrite of connection-scoping methodology, Connection objects
-can now execute clause elements directly, added explicit "close" as
-well as support throughout Engine/ORM to handle closing properly,
-no longer relying upon __del__ internally to return connections
-to the pool [ticket:152].
-- overhaul to Session interface and scoping.  uses hibernate-style
-methods, including query(class), save(), save_or_update(), etc.
-no threadlocal scope is installed by default.  Provides a binding
-interface to specific Engines and/or Connections so that underlying
-Schema objects do not need to be bound to an Engine.  Added a basic
-SessionTransaction object that can simplistically aggregate transactions
-across multiple engines.
-- overhaul to mapper's dependency and "cascade" behavior; dependency logic
-factored out of properties.py into a separate module "dependency.py".
-"cascade" behavior is now explicitly controllable, proper implementation
-of "delete", "delete-orphan", etc.  dependency system can now determine at
-flush time if a child object has a parent or not so that it makes better
-decisions on how that child should be updated in the DB with regards to deletes.
-- overhaul to Schema to build upon MetaData object instead of an Engine.
-Entire SQL/Schema system can be used with no Engines whatsoever, executed
-solely by an explicit Connection object.  the "bound" methodlogy exists via the
-BoundMetaData for schema objects.  ProxyEngine is generally not needed
-anymore and is replaced by DynamicMetaData.
-- true polymorphic behavior implemented, fixes [ticket:167]
-- "oid" system has been totally moved into compile-time behavior;
-if they are used in an order_by where they are not available, the order_by
-doesnt get compiled, fixes [ticket:147]
-- overhaul to packaging; "mapping" is now "orm", "objectstore" is now
-"session", the old "objectstore" namespace gets loaded in via the
-"threadlocal" mod if used
-- mods now called in via "import <modname>".  extensions favored over
-mods as mods are globally-monkeypatching
-- fix to add_property so that it propagates properties to inheriting
-mappers [ticket:154]
-- backrefs create themselves against primary mapper of its originating
-property, priamry/secondary join arguments can be specified to override.
-helps their usage with polymorphic mappers
-- "table exists" function has been implemented [ticket:31]
-- "create_all/drop_all" added to MetaData object [ticket:98]
-- improvements and fixes to topological sort algorithm, as well as more
-unit tests
-- tutorial page added to docs which also can be run with a custom doctest
-runner to ensure its properly working.  docs generally overhauled to
-deal with new code patterns
-- many more fixes, refactorings.
-- migration guide is available on the Wiki at
-http://www.sqlalchemy.org/trac/wiki/02Migration
-
-0.1.7
-- some fixes to topological sort algorithm
-- added DISTINCT ON support to Postgres (just supply distinct=[col1,col2..])
-- added __mod__ (% operator) to sql expressions
-- "order_by" mapper property inherited from inheriting mapper
-- fix to column type used when mapper UPDATES/DELETEs
-- with convert_unicode=True, reflection was failing, has been fixed
-- types types types!  still werent working....have to use TypeDecorator again :(
-- mysql binary type converts array output to buffer, fixes PickleType
-- fixed the attributes.py memory leak once and for all
-- unittests are qualified based on the databases that support each one
-- fixed bug where column defaults would clobber VALUES clause of insert objects
-- fixed bug where table def w/ schema name would force engine connection
-- fix for parenthesis to work correctly with subqueries in INSERT/UPDATE
-- HistoryArraySet gets extend() method
-- fixed lazyload support for other comparison operators besides =
-- lazyload fix where two comparisons in the join condition point to the
-samem column
-- added "construct_new" flag to mapper, will use __new__ to create instances
-instead of __init__ (standard in 0.2)
-- added selectresults.py to SVN, missed it last time
-- tweak to allow a many-to-many relationship from a table to itself via
-an association table
-- small fix to "translate_row" function used by polymorphic example
-- create_engine uses cgi.parse_qsl to read query string (out the window in 0.2)
-- tweaks to CAST operator
-- fixed function names LOCAL_TIME/LOCAL_TIMESTAMP -> LOCALTIME/LOCALTIMESTAMP
-- fixed order of ORDER BY/HAVING in compile
-
-0.1.6
-- support for MS-SQL added courtesy Rick Morrison, Runar Petursson
-- the latest SQLSoup from J. Ellis
-- ActiveMapper has preliminary support for inheritance (Jeff Watkins)
-- added a "mods" system which allows pluggable modules that modify/augment
-core functionality, using the function "install_mods(*modnames)".
-- added the first "mod", SelectResults, which modifies mapper selects to
-return generators that turn ranges into LIMIT/OFFSET queries (Jonas Borgstr?- factored out querying capabilities of Mapper into a separate Query object
-which is Session-centric.  this improves the performance of mapper.using(session)
-and makes other things possible.
-- objectstore/Session refactored, the official way to save objects is now
-via the flush() method.  The begin/commit functionality of Session is factored
-into LegacySession which is still established as the default behavior, until
-the 0.2 series.
-- types system is bound to an engine at query compile time, not schema
-construction time.  this simplifies the types system as well as the ProxyEngine.
-- added 'version_id' keyword argument to mapper. this keyword should reference a
-Column object with type Integer, preferably non-nullable, which will be used on
-the mapped table to track version numbers. this number is incremented on each
-save operation and is specifed in the UPDATE/DELETE conditions so that it
-factors into the returned row count, which results in a ConcurrencyError if the
-value received is not the expected count.
-- added 'entity_name' keyword argument to mapper. a mapper is now associated
-with a class via the class object as well as an optional entity_name parameter,
-which is a string defaulting to None. any number of primary mappers can be
-created for a class, qualified by the entity name. instances of those classes
-will issue all of their load and save operations through their
-entity_name-qualified mapper, and maintain separate a identity in the identity
-map for an otherwise equilvalent object.
-- overhaul to the attributes system. code has been clarified, and also fixed to
-support proper polymorphic behavior on object attributes.
-- added "for_update" flag to Select objects
-- some fixes for backrefs
-- fix for postgres1 DateTime type
-- documentation pages mostly switched over to Markdown syntax
-
-0.1.5
-- added SQLSession concept to SQLEngine. this object keeps track of retrieving a
-connection from the connection pool as well as an in-progress transaction.
-methods push_session() and pop_session() added to SQLEngine which push/pop a new
-SQLSession onto the engine, allowing operation upon a second connection "nested"
-within the previous one, allowing nested transactions. Other tricks are sure to
-come later regarding SQLSession.
-- added nest_on argument to objectstore.Session. This is a single SQLEngine or
-list of engines for which push_session()/pop_session() will be called each time
-this Session becomes the active session (via objectstore.push_session() or
-equivalent). This allows a unit of work Session to take advantage of the nested
-transaction feature without explicitly calling push_session/pop_session on the
-engine.
-- factored apart objectstore/unitofwork to separate "Session scoping" from
-"uow commit heavy lifting"
-- added populate_instance() method to MapperExtension. allows an extension to
-modify the population of object attributes. this method can call the
-populate_instance() method on another mapper to proxy the attribute population
-from one mapper to another; some row translation logic is also built in to help
-with this.
-- fixed Oracle8-compatibility "use_ansi" flag which converts JOINs to
-comparisons with the = and (+) operators, passes basic unittests
-- tweaks to Oracle LIMIT/OFFSET support
-- Oracle reflection uses ALL_** views instead of USER_** to get larger
-list of stuff to reflect from
-- fixes to Oracle foreign key reflection [ticket:105]
-- objectstore.commit(obj1, obj2,...) adds an extra step to seek out private
-relations on properties and delete child objects, even though its not a global
-commit
-- lots and lots of fixes to mappers which use inheritance, strengthened the
-concept of relations on a mapper being made towards the "local" table for that
-mapper, not the tables it inherits.  allows more complex compositional patterns
-to work with lazy/eager loading.
-- added support for mappers to inherit from others based on the same table,
-just specify the same table as that of both parent/child mapper.
-- some minor speed improvements to the attributes system with regards to
-instantiating and populating new objects.
-- fixed MySQL binary unit test
-- INSERTs can receive clause elements as VALUES arguments, not just literal
-values
-- support for calling multi-tokened functions, i.e. schema.mypkg.func()
-- added J. Ellis' SQLSoup module to extensions package
-- added "polymorphic" examples illustrating methods to load multiple object types
-from one mapper, the second of which uses the new populate_instance() method.
-small improvements to mapper, UNION construct to help the examples along
-- improvements/fixes to session.refresh()/session.expire() (which may have
-been called "invalidate" earlier..)
-- added session.expunge() which totally removes an object from the current
-session
-- added *args, **kwargs pass-thru to engine.transaction(func) allowing easier
-creation of transactionalizing decorator functions
-- added iterator interface to ResultProxy:  "for row in result:..."
-- added assertion to tx = session.begin(); tx.rollback(); tx.begin(), i.e. cant
-use it after a rollback()
-- added date conversion on bind parameter fix to SQLite enabling dates to
-work with pysqlite1
-- improvements to subqueries to more intelligently construct their FROM
-clauses [ticket:116]
-- added PickleType to types.
-- fixed two bugs with column labels with regards to bind parameters: bind param
-keynames they are now generated from a column "label" in all relevant cases to
-take advantage of excess-name-length rules, and checks for a peculiar collision
-against a column named the same as "tablename_colname" added
-- major overhaul to unit of work documentation, other documentation sections.
-- fixed attributes bug where if an object is committed, its lazy-loaded list got
-blown away if it hadnt been loaded
-- added unique_connection() method to engine, connection pool to return a
-connection that is not part of the thread-local context or any current
-transaction
-- added invalidate() function to pooled connection.  will remove the connection
-from the pool.  still need work for engines to auto-reconnect to a stale DB
-though.
-- added distinct() function to column elements so you can do
-func.count(mycol.distinct())
-- added "always_refresh" flag to Mapper, creates a mapper that will always
-refresh the attributes of objects it gets/selects from the DB, overwriting any
-changes made.
-
-0.1.4
-- create_engine() now uses genericized parameters; host/hostname,
-db/dbname/database, password/passwd, etc. for all engine connections. makes
- engine URIs much more "universal"
-- added support for SELECT statements embedded into a column clause, using the
-flag "scalar=True"
-- another overhaul to EagerLoading when used in conjunction with mappers that
-inherit; improvements to eager loads figuring out their aliased queries
-correctly, also relations set up against a mapper with inherited mappers will
-create joins against the table that is specific to the mapper itself (i.e. and
-not any tables that are inherited/are further down the inheritance chain),
-this can be overridden by using custom primary/secondary joins.
-- added J.Ellis patch to mapper.py so that selectone() throws an exception
-if query returns more than one object row, selectfirst() to not throw the
-exception. also adds selectfirst_by (synonymous with get_by) and selectone_by
-- added onupdate parameter to Column, will exec SQL/python upon an update
-statement.Also adds "for_update=True" to all DefaultGenerator subclasses
-- added support for Oracle table reflection contributed by Andrija Zaric;
-still some bugs to work out regarding composite primary keys/dictionary selection
-- checked in an initial Firebird module, awaiting testing.
-- added sql.ClauseParameters dictionary object as the result for
-compiled.get_params(), does late-typeprocessing of bind parameters so
-that the original values are easier to access
-- more docs for indexes, column defaults, connection pooling, engine construction
-- overhaul to the construction of the types system. uses a simpler inheritance
-pattern so that any of the generic types can be easily subclassed, with no need
-for TypeDecorator.
-- added "convert_unicode=False" parameter to SQLEngine, will cause all String
-types to perform unicode encoding/decoding (makes Strings act like Unicodes)
-- added 'encoding="utf8"' parameter to engine.  the given encoding will be
-used for all encode/decode calls within Unicode types as well as Strings
-when convert_unicode=True.
-- improved support for mapping against UNIONs, added polymorph.py example
-to illustrate multi-class mapping against a UNION
-- fix to SQLite LIMIT/OFFSET syntax
-- fix to Oracle LIMIT syntax
-- added backref() function, allows backreferences to have keyword arguments
-that will be passed to the backref.
-- Sequences and ColumnDefault objects can do execute()/scalar() standalone
-- SQL functions (i.e. func.foo()) can do execute()/scalar() standalone
-- fix to SQL functions so that the ANSI-standard functions, i.e. current_timestamp
-etc., do not specify parenthesis.  all other functions do.
-- added settattr_clean and append_clean to SmartProperty, which set
-attributes without triggering a "dirty" event or any history. used as:
-myclass.prop1.setattr_clean(myobject, 'hi')
-- improved support to column defaults when used by mappers; mappers will pull
-pre-executed defaults from statement's executed bind parameters
-(pre-conversion) to populate them into a saved object's attributes; if any
-PassiveDefaults have fired off, will instead post-fetch the row from the DB to
-populate the object.
-- added 'get_session().invalidate(*obj)' method to objectstore, instances will
-refresh() themselves upon the next attribute access.
-- improvements to SQL func calls including an "engine" keyword argument so
-they can be execute()d or scalar()ed standalone, also added func accessor to
-SQLEngine
-- fix to MySQL4 custom table engines, i.e. TYPE instead of ENGINE
-- slightly enhanced logging, includes timestamps and a somewhat configurable
-formatting system, in lieu of a full-blown logging system
-- improvements to the ActiveMapper class from the TG gang, including
-many-to-many relationships
-- added Double and TinyInt support to mysql
-
-0.1.3
-- completed "post_update" feature, will add a second update statement before
-inserts and after deletes in order to reconcile a relationship without any
-dependencies being created; used when persisting two rows that are dependent
-on each other
-- completed mapper.using(session) function, localized per-object Session
-functionality; objects can be declared and manipulated as local to any
-user-defined Session
-- fix to Oracle "row_number over" clause with multiple tables
-- mapper.get() was not selecting multiple-keyed objects if the mapper's table was a join,
-such as in an inheritance relationship, this is fixed.
-- overhaul to sql/schema packages so that the sql package can run all on its own,
-producing selects, inserts, etc. without any engine dependencies.  builds upon
-new TableClause/ColumnClause lexical objects.  Schema's Table/Column objects
-are the "physical" subclasses of them.  simplifies schema/sql relationship,
-extensions (like proxyengine), and speeds overall performance by a large margin.
-removes the entire getattr() behavior that plagued 0.1.1.
-- refactoring of how the mapper "synchronizes" data between two objects into a
-separate module, works better with properties attached to a mapper that has an
-additional inheritance relationship to one of the related tables, also the same
-methodology used to synchronize parent/child objects now used by mapper to
-synchronize between inherited and inheriting mappers.
-- made objectstore "check for out-of-identitymap" more aggressive, will perform the
-check when object attributes are modified or the object is deleted
-- Index object fully implemented, can be constructed standalone, or via
-"index" and "unique" arguments on Columns.
-- added "convert_unicode" flag to SQLEngine, will treat all String/CHAR types
-as Unicode types, with raw-byte/utf-8 translation on the bind parameter and
-result set side.
-- postgres maintains a list of ANSI functions that must have no parenthesis so
-function calls with no arguments work consistently
-- tables can be created with no engine specified.  this will default their engine
-to a module-scoped "default engine" which is a ProxyEngine.  this engine can
-be connected via the function "global_connect".
-- added "refresh(*obj)" method to objectstore / Session to reload the attributes of
-any set of objects from the database unconditionally
-
-0.1.2
-- fixed a recursive call in schema that was somehow running 994 times then returning
-normally.  broke nothing, slowed down everything.  thanks to jpellerin for finding this.
-
-0.1.1
-- small fix to Function class so that expressions with a func.foo() use the type of the
-Function object (i.e. the left side) as the type of the boolean expression, not the
-other side which is more of a moving target (changeset 1020).
-- creating self-referring mappers with backrefs slightly easier (but still not that easy -
-changeset 1019)
-- fixes to one-to-one mappings (changeset 1015)
-- psycopg1 date/time issue with None fixed (changeset 1005)
-- two issues related to postgres, which doesnt want to give you the "lastrowid"
-since oids are deprecated:
-   * postgres database-side defaults that are on primary key cols *do* execute
-explicitly beforehand, even though thats not the idea of a PassiveDefault.  this is
-because sequences on columns get reflected as PassiveDefaults, but need to be explicitly
-executed on a primary key col so we know what we just inserted.
-   * if you did add a row that has a bunch of database-side defaults on it,
-and the PassiveDefault thing was working the old way, i.e. they just execute on
-the DB side, the "cant get the row back without an OID" exception that occurred
-also will not happen unless someone (usually the ORM) explicitly asks for it.
-- fixed a glitch with engine.execute_compiled where it was making a second
-ResultProxy that just got thrown away.
-- began to implement newer logic in object properities.  you can now say
-myclass.attr.property, which will give you the PropertyLoader corresponding to that
-attribute, i.e. myclass.mapper.props['attr']
-- eager loading has been internally overhauled to use aliases at all times.  more
-complicated chains of eager loads can now be created without any need for explicit
-"use aliases"-type instructions.  EagerLoader code is also much simpler now.
-- a new somewhat experimental flag "use_update" added to relations, indicates that
-this relationship should be handled by a second UPDATE statement, either after a
-primary INSERT or before a primary DELETE.  handles circular row dependencies.
-- added exceptions module, all raised exceptions (except for some
-KeyError/AttributeError exceptions) descend from these classes.
-- fix to date types with MySQL, returned timedelta converted to datetime.time
-- two-phase objectstore.commit operations (i.e. begin/commit) now return a
-transactional object (SessionTrans), to more clearly indicate transaction boundaries.
-- Index object with create/drop support added to schema
-- fix to postgres, where it will explicitly pre-execute a PassiveDefault on a table
-if it is a primary key column, pursuant to the ongoing "we cant get inserted rows
-back from postgres" issue
-- change to information_schema query that gets back postgres table defs, now
-uses explicit JOIN keyword, since one user had faster performance with 8.1
-- fix to engine.process_defaults so it works correctly with a table that has
-different column name/column keys (changset 982)
-- a column can only be attached to one table - this is now asserted
-- postgres time types descend from Time type
-- fix to alltests so that it runs types test (now named testtypes)
-- fix to Join object so that it correctly exports its foreign keys (cs 973)
-- creating relationships against mappers that use inheritance fixed (cs 973)
-
-0.1.0
-initial release
-
+For changes prior to 0.5, see CHANGES_PRE_05
 
diff --git a/CHANGES_PRE_05 b/CHANGES_PRE_05
new file mode 100644 (file)
index 0000000..6291375
--- /dev/null
@@ -0,0 +1,4107 @@
+-*- coding: utf-8; fill-column: 68 -*-
+
+===============
+CHANGES PRE-0.5
+===============
+
+0.4.7
+=====
+- orm
+    - The contains() operator when used with many-to-many
+      will alias() the secondary (association) table so
+      that multiple contains() calls will not conflict
+      with each other [ticket:1058]
+
+    - fixed bug preventing merge() from functioning in
+      conjunction with a comparable_property()
+
+    - the enable_typechecks=False setting on relation()
+      now only allows subtypes with inheriting mappers.
+      Totally unrelated types, or subtypes not set up with
+      mapper inheritance against the target mapper are
+      still not allowed.
+
+    - Added is_active flag to Sessions to detect when
+      a transaction is in progress [ticket:976].  This
+      flag is always True with a "transactional"
+      (in 0.5 a non-"autocommit") Session.
+
+- sql
+    - Fixed bug when calling select([literal('foo')])
+      or select([bindparam('foo')]).
+
+- schema
+    - create_all(), drop_all(), create(), drop() all raise
+      an error if the table name or schema name contains
+      more characters than that dialect's configured
+      character limit.  Some DB's can handle too-long
+      table names during usage, and SQLA can handle this
+      as well. But various reflection/
+      checkfirst-during-create scenarios fail since we are
+      looking for the name within the DB's catalog tables.
+      [ticket:571]
+
+    - The index name generated when you say "index=True"
+      on a Column is truncated to the length appropriate
+      for the dialect. Additionally, an Index with a too-
+      long name cannot be explicitly dropped with
+      Index.drop(), similar to [ticket:571].
+      [ticket:820]
+
+- postgres
+    - Repaired server_side_cursors to properly detect
+      text() clauses.
+
+    - Added PGCidr type. [ticket:1092]
+
+- mysql
+    - Added 'CALL' to the list of SQL keywords which return
+      result rows.
+
+- oracle
+    - Oracle get_default_schema_name() "normalizes" the name
+      before returning, meaning it returns a lower-case name
+      when the identifier is detected as case insensitive.
+
+    - creating/dropping tables takes schema name into account
+      when searching for the existing table, so that tables
+      in other owner namespaces with the same name do not
+      conflict [ticket:709]
+
+    - Cursors now have "arraysize" set to 50 by default on
+      them, the value of which is configurable using the
+      "arraysize" argument to create_engine() with the
+      Oracle dialect.  This to account for cx_oracle's default
+      setting of "1", which has the effect of many round trips
+      being sent to Oracle.  This actually works well in
+      conjunction with BLOB/CLOB-bound cursors, of which
+      there are any number available but only for the life of
+      that row request (so BufferedColumnRow is still needed,
+      but less so). [ticket:1062]
+
+- sqlite
+      - add SLFloat type, which matches the SQLite REAL
+        type affinity.  Previously, only SLNumeric was provided
+        which fulfills NUMERIC affinity, but that's not the
+        same as REAL.
+
+0.4.6
+=====
+- orm
+    - Fix to the recent relation() refactoring which fixes
+      exotic viewonly relations which join between local and
+      remote table multiple times, with a common column shared
+      between the joins.
+
+    - Also re-established viewonly relation() configurations
+      that join across multiple tables.
+
+    - Added experimental relation() flag to help with
+      primaryjoins across functions, etc.,
+      _local_remote_pairs=[tuples].  This complements a complex
+      primaryjoin condition allowing you to provide the
+      individual column pairs which comprise the relation's
+      local and remote sides.  Also improved lazy load SQL
+      generation to handle placing bind params inside of
+      functions and other expressions.  (partial progress
+      towards [ticket:610])
+
+    - repaired single table inheritance such that you
+      can single-table inherit from a joined-table inherting
+      mapper without issue [ticket:1036].
+
+    - Fixed "concatenate tuple" bug which could occur with
+      Query.order_by() if clause adaption had taken place.
+      [ticket:1027]
+
+    - Removed ancient assertion that mapped selectables require
+      "alias names" - the mapper creates its own alias now if
+      none is present.  Though in this case you need to use the
+      class, not the mapped selectable, as the source of column
+      attributes - so a warning is still issued.
+
+    - fixes to the "exists" function involving inheritance (any(),
+      has(), ~contains()); the full target join will be rendered
+      into the EXISTS clause for relations that link to subclasses.
+
+    - restored usage of append_result() extension method for primary
+      query rows, when the extension is present and only a single-
+      entity result is being returned.
+
+    - Also re-established viewonly relation() configurations that
+      join across multiple tables.
+
+    - removed ancient assertion that mapped selectables require
+      "alias names" - the mapper creates its own alias now if
+      none is present.  Though in this case you need to use
+      the class, not the mapped selectable, as the source of
+      column attributes - so a warning is still issued.
+
+    - refined mapper._save_obj() which was unnecessarily calling
+      __ne__() on scalar values during flush [ticket:1015]
+
+    - added a feature to eager loading whereby subqueries set
+      as column_property() with explicit label names (which is not
+      necessary, btw) will have the label anonymized when
+      the instance is part of the eager join, to prevent
+      conflicts with a subquery or column of the same name
+      on the parent object.  [ticket:1019]
+
+    - set-based collections |=, -=, ^= and &= are stricter about
+      their operands and only operate on sets, frozensets or
+      subclasses of the collection type. Previously, they would
+      accept any duck-typed set.
+
+    - added an example dynamic_dict/dynamic_dict.py, illustrating
+      a simple way to place dictionary behavior on top of
+      a dynamic_loader.
+
+- declarative extension
+    - Joined table inheritance mappers use a slightly relaxed
+      function to create the "inherit condition" to the parent
+      table, so that other foreign keys to not-yet-declared
+      Table objects don't trigger an error.
+
+    - fixed reentrant mapper compile hang when
+      a declared attribute is used within ForeignKey,
+      ie. ForeignKey(MyOtherClass.someattribute)
+
+- sql
+    - Added COLLATE support via the .collate(<collation>)
+      expression operator and collate(<expr>, <collation>) sql
+      function.
+
+    - Fixed bug with union() when applied to non-Table connected
+      select statements
+
+    - improved behavior of text() expressions when used as
+      FROM clauses, such as select().select_from(text("sometext"))
+      [ticket:1014]
+
+    - Column.copy() respects the value of "autoincrement",
+      fixes usage with Migrate [ticket:1021]
+
+- engines
+    - Pool listeners can now be provided as a dictionary of
+      callables or a (possibly partial) duck-type of
+      PoolListener, your choice.
+
+    - added "rollback_returned" option to Pool which will
+      disable the rollback() issued when connections are
+      returned.  This flag is only safe to use with a database
+      which does not support transactions (i.e. MySQL/MyISAM).
+
+- ext
+    - set-based association proxies |=, -=, ^= and &= are
+      stricter about their operands and only operate on sets,
+      frozensets or other association proxies. Previously, they
+      would accept any duck-typed set.
+
+- mssql
+    - Added "odbc_autotranslate" parameter to engine / dburi
+      parameters. Any given string will be passed through to the
+      ODBC connection string as:
+
+            "AutoTranslate=%s" % odbc_autotranslate
+
+      [ticket:1005]
+
+    - Added "odbc_options" parameter to engine / dburi
+      parameters. The given string is simply appended to the
+      SQLAlchemy-generated odbc connection string.
+
+      This should obviate the need of adding a myriad of ODBC
+      options in the future.
+
+- firebird
+    - Handle the "SUBSTRING(:string FROM :start FOR :length)"
+      builtin.
+
+0.4.5
+=====
+- orm
+    - A small change in behavior to session.merge() - existing
+      objects are checked for based on primary key attributes, not
+      necessarily _instance_key.  So the widely requested
+      capability, that:
+
+            x = MyObject(id=1)
+            x = sess.merge(x)
+
+      will in fact load MyObject with id #1 from the database if
+      present, is now available.  merge() still copies the state
+      of the given object to the persistent one, so an example
+      like the above would typically have copied "None" from all
+      attributes of "x" onto the persistent copy.  These can be
+      reverted using session.expire(x).
+
+    - Also fixed behavior in merge() whereby collection elements
+      present on the destination but not the merged collection
+      were not being removed from the destination.
+
+    - Added a more aggressive check for "uncompiled mappers",
+      helps particularly with declarative layer [ticket:995]
+
+    - The methodology behind "primaryjoin"/"secondaryjoin" has
+      been refactored.  Behavior should be slightly more
+      intelligent, primarily in terms of error messages which
+      have been pared down to be more readable.  In a slight
+      number of scenarios it can better resolve the correct
+      foreign key than before.
+
+    - Added comparable_property(), adds query Comparator
+      behavior to regular, unmanaged Python properties
+
+    - the functionality of query.with_polymorphic() has
+      been added to mapper() as a configuration option.
+
+      It's set via several forms:
+            with_polymorphic='*'
+            with_polymorphic=[mappers]
+            with_polymorphic=('*', selectable)
+            with_polymorphic=([mappers], selectable)
+
+      This controls the default polymorphic loading strategy
+      for inherited mappers. When a selectable is not given,
+      outer joins are created for all joined-table inheriting
+      mappers requested. Note that the auto-create of joins
+      is not compatible with concrete table inheritance.
+
+      The existing select_table flag on mapper() is now
+      deprecated and is synonymous with
+      with_polymorphic('*', select_table).  Note that the
+      underlying "guts" of select_table have been
+      completely removed and replaced with the newer,
+      more flexible approach.
+
+      The new approach also automatically allows eager loads
+      to work for subclasses, if they are present, for
+      example
+        sess.query(Company).options(
+         eagerload_all(
+          [Company.employees.of_type(Engineer), 'machines']
+        ))
+      to load Company objects, their employees, and the
+      'machines' collection of employees who happen to be
+      Engineers. A "with_polymorphic" Query option should be
+      introduced soon as well which would allow per-Query
+      control of with_polymorphic() on relations.
+
+    - added two "experimental" features to Query,
+      "experimental" in that their specific name/behavior
+      is not carved in stone just yet:  _values() and
+      _from_self().  We'd like feedback on these.
+
+      - _values(*columns) is given a list of column
+        expressions, and returns a new Query that only
+        returns those columns. When evaluated, the return
+        value is a list of tuples just like when using
+        add_column() or add_entity(), the only difference is
+        that "entity zero", i.e. the mapped class, is not
+        included in the results. This means it finally makes
+        sense to use group_by() and having() on Query, which
+        have been sitting around uselessly until now.
+
+        A future change to this method may include that its
+        ability to join, filter and allow other options not
+        related to a "resultset" are removed, so the feedback
+        we're looking for is how people want to use
+        _values()...i.e. at the very end, or do people prefer
+        to continue generating after it's called.
+
+      - _from_self() compiles the SELECT statement for the
+        Query (minus any eager loaders), and returns a new
+        Query that selects from that SELECT. So basically you
+        can query from a Query without needing to extract the
+        SELECT statement manually. This gives meaning to
+        operations like query[3:5]._from_self().filter(some
+        criterion). There's not much controversial here
+        except that you can quickly create highly nested
+        queries that are less efficient, and we want feedback
+        on the naming choice.
+
+    - query.order_by() and query.group_by() will accept
+      multiple arguments using *args (like select()
+      already does).
+
+    - Added some convenience descriptors to Query:
+      query.statement returns the full SELECT construct,
+      query.whereclause returns just the WHERE part of the
+      SELECT construct.
+
+    - Fixed/covered case when using a False/0 value as a
+      polymorphic discriminator.
+
+    - Fixed bug which was preventing synonym() attributes from
+      being used with inheritance
+
+    - Fixed SQL function truncation of trailing underscores
+      [ticket:996]
+
+    - When attributes are expired on a pending instance, an
+      error will not be raised when the "refresh" action is
+      triggered and no result is found.
+
+    - Session.execute can now find binds from metadata
+
+    - Adjusted the definition of "self-referential" to be any
+      two mappers with a common parent (this affects whether or
+      not aliased=True is required when joining with Query).
+
+    - Made some fixes to the "from_joinpoint" argument to
+      query.join() so that if the previous join was aliased and
+      this one isn't, the join still happens successfully.
+
+    - Assorted "cascade deletes" fixes:
+        - Fixed "cascade delete" operation of dynamic relations,
+          which had only been implemented for foreign-key
+          nulling behavior in 0.4.2 and not actual cascading
+          deletes [ticket:895]
+
+        - Delete cascade without delete-orphan cascade on a
+          many-to-one will not delete orphans which were
+          disconnected from the parent before session.delete()
+          is called on the parent (one-to-many already had
+          this).
+
+        - Delete cascade with delete-orphan will delete orphans
+          whether or not it remains attached to its also-deleted
+          parent.
+
+        - delete-orphan casacde is properly detected on relations
+          that are present on superclasses when using inheritance.
+
+    - Fixed order_by calculation in Query to properly alias
+      mapper-config'ed order_by when using select_from()
+
+    - Refactored the diffing logic that kicks in when replacing
+      one collection with another into collections.bulk_replace,
+      useful to anyone building multi-level collections.
+
+    - Cascade traversal algorithm converted from recursive to
+      iterative to support deep object graphs.
+
+- sql
+    - schema-qualified tables now will place the schemaname
+      ahead of the tablename in all column expressions as well
+      as when generating column labels.  This prevents cross-
+      schema name collisions in all cases [ticket:999]
+
+    - can now allow selects which correlate all FROM clauses
+      and have no FROM themselves.  These are typically
+      used in a scalar context, i.e. SELECT x, (SELECT x WHERE y)
+      FROM table.  Requires explicit correlate() call.
+
+    - 'name' is no longer a required constructor argument for
+      Column().  It (and .key) may now be deferred until the
+      column is added to a Table.
+
+    - like(), ilike(), contains(), startswith(), endswith() take
+      an optional keyword argument "escape=<somestring>", which
+      is set as the escape character using the syntax "x LIKE y
+      ESCAPE '<somestring>'" [ticket:993], [ticket:791]
+
+    - random() is now a generic sql function and will compile to
+      the database's random implementation, if any.
+
+    - update().values() and insert().values() take keyword
+      arguments.
+
+    - Fixed an issue in select() regarding its generation of
+      FROM clauses, in rare circumstances two clauses could be
+      produced when one was intended to cancel out the other.
+      Some ORM queries with lots of eager loads might have seen
+      this symptom.
+
+    - The case() function now also takes a dictionary as its
+      whens parameter.  It also interprets the "THEN"
+      expressions as values by default, meaning case([(x==y,
+      "foo")]) will interpret "foo" as a bound value, not a SQL
+      expression.  use text(expr) for literal SQL expressions in
+      this case.  For the criterion itself, these may be literal
+      strings only if the "value" keyword is present, otherwise
+      SA will force explicit usage of either text() or
+      literal().
+
+- oracle
+    - The "owner" keyword on Table is now deprecated, and is
+      exactly synonymous with the "schema" keyword.  Tables can
+      now be reflected with alternate "owner" attributes,
+      explicitly stated on the Table object or not using
+      "schema".
+
+    - All of the "magic" searching for synonyms, DBLINKs etc.
+      during table reflection are disabled by default unless you
+      specify "oracle_resolve_synonyms=True" on the Table
+      object.  Resolving synonyms necessarily leads to some
+      messy guessing which we'd rather leave off by default.
+      When the flag is set, tables and related tables will be
+      resolved against synonyms in all cases, meaning if a
+      synonym exists for a particular table, reflection will use
+      it when reflecting related tables.  This is stickier
+      behavior than before which is why it's off by default.
+
+- declarative extension
+    - The "synonym" function is now directly usable with
+      "declarative".  Pass in the decorated property using the
+      "descriptor" keyword argument, e.g.: somekey =
+      synonym('_somekey', descriptor=property(g, s))
+
+    - The "deferred" function is usable with "declarative".
+      Simplest usage is to declare deferred and Column together,
+      e.g.: data = deferred(Column(Text))
+
+    - Declarative also gained @synonym_for(...) and
+      @comparable_using(...), front-ends for synonym and
+      comparable_property.
+
+    - Improvements to mapper compilation when using declarative;
+      already-compiled mappers will still trigger compiles of
+      other uncompiled mappers when used [ticket:995]
+
+    - Declarative will complete setup for Columns lacking names,
+      allows a more DRY syntax.
+
+        class Foo(Base):
+            __tablename__ = 'foos'
+            id = Column(Integer, primary_key=True)
+
+     - inheritance in declarative can be disabled when sending
+       "inherits=None" to __mapper_args__.
+
+     - declarative_base() takes optional kwarg "mapper", which
+       is any callable/class/method that produces a mapper,
+       such as declarative_base(mapper=scopedsession.mapper).
+       This property can also be set on individual declarative
+       classes using the "__mapper_cls__" property.
+
+- postgres
+    - Got PG server side cursors back into shape, added fixed
+      unit tests as part of the default test suite.  Added
+      better uniqueness to the cursor ID [ticket:1001]
+
+- oracle
+    - The "owner" keyword on Table is now deprecated, and is
+      exactly synonymous with the "schema" keyword.  Tables can
+      now be reflected with alternate "owner" attributes,
+      explicitly stated on the Table object or not using
+      "schema".
+
+    - All of the "magic" searching for synonyms, DBLINKs etc.
+      during table reflection are disabled by default unless you
+      specify "oracle_resolve_synonyms=True" on the Table
+      object.  Resolving synonyms necessarily leads to some
+      messy guessing which we'd rather leave off by default.
+      When the flag is set, tables and related tables will be
+      resolved against synonyms in all cases, meaning if a
+      synonym exists for a particular table, reflection will use
+      it when reflecting related tables.  This is stickier
+      behavior than before which is why it's off by default.
+
+- mssql
+     - Reflected tables will now automatically load other tables
+       which are referenced by Foreign keys in the auto-loaded
+       table, [ticket:979].
+
+     - Added executemany check to skip identity fetch, [ticket:916].
+
+     - Added stubs for small date type, [ticket:884]
+
+     - Added a new 'driver' keyword parameter for the pyodbc dialect.
+       Will substitute into the ODBC connection string if given,
+       defaults to 'SQL Server'.
+
+     - Added a new 'max_identifier_length' keyword parameter for
+       the pyodbc dialect.
+
+     - Improvements to pyodbc + Unix. If you couldn't get that
+       combination to work before, please try again.
+
+- mysql
+     - The connection.info keys the dialect uses to cache server
+       settings have changed and are now namespaced.
+
+0.4.4
+------
+- sql
+    - Can again create aliases of selects against textual FROM
+      clauses, [ticket:975]
+
+    - The value of a bindparam() can be a callable, in which
+      case it's evaluated at statement execution time to get the
+      value.
+
+    - Added exception wrapping/reconnect support to result set
+      fetching.  Reconnect works for those databases that raise
+      a catchable data error during results (i.e. doesn't work
+      on MySQL) [ticket:978]
+
+    - Implemented two-phase API for "threadlocal" engine, via
+      engine.begin_twophase(), engine.prepare() [ticket:936]
+
+    - Fixed bug which was preventing UNIONS from being
+      cloneable, [ticket:986]
+
+    - Added "bind" keyword argument to insert(), update(),
+      delete() and DDL(). The .bind property is now assignable
+      on those statements as well as on select().
+
+    - Insert statements can now be compiled with extra "prefix"
+      words between INSERT and INTO, for vendor extensions like
+      MySQL's INSERT IGNORE INTO table.
+
+- orm
+    - any(), has(), contains(), ~contains(), attribute level ==
+      and != now work properly with self-referential relations -
+      the clause inside the EXISTS is aliased on the "remote"
+      side to distinguish it from the parent table.  This
+      applies to single table self-referential as well as
+      inheritance-based self-referential.
+
+    - Repaired behavior of == and != operators at the relation()
+      level when compared against NULL for one-to-one relations
+      [ticket:985]
+
+    - Fixed bug whereby session.expire() attributes were not
+      loading on an polymorphically-mapped instance mapped by a
+      select_table mapper.
+
+    - Added query.with_polymorphic() - specifies a list of
+      classes which descend from the base class, which will be
+      added to the FROM clause of the query.  Allows subclasses
+      to be used within filter() criterion as well as eagerly
+      loads the attributes of those subclasses.
+
+    - Your cries have been heard: removing a pending item from
+      an attribute or collection with delete-orphan expunges the
+      item from the session; no FlushError is raised.  Note that
+      if you session.save()'ed the pending item explicitly, the
+      attribute/collection removal still knocks it out.
+
+    - session.refresh() and session.expire() raise an error when
+      called on instances which are not persistent within the
+      session
+
+    - Fixed potential generative bug when the same Query was
+      used to generate multiple Query objects using join().
+
+    - Fixed bug which was introduced in 0.4.3, whereby loading
+      an already-persistent instance mapped with joined table
+      inheritance would trigger a useless "secondary" load from
+      its joined table, when using the default "select"
+      polymorphic_fetch.  This was due to attributes being
+      marked as expired during its first load and not getting
+      unmarked from the previous "secondary" load.  Attributes
+      are now unexpired based on presence in __dict__ after any
+      load or commit operation succeeds.
+
+    - Deprecated Query methods apply_sum(), apply_max(),
+      apply_min(), apply_avg().  Better methodologies are
+      coming....
+
+    - relation() can accept a callable for its first argument,
+      which returns the class to be related.  This is in place
+      to assist declarative packages to define relations without
+      classes yet being in place.
+
+    - Added a new "higher level" operator called "of_type()":
+      used in join() as well as with any() and has(), qualifies
+      the subclass which will be used in filter criterion, e.g.:
+
+        query.filter(Company.employees.of_type(Engineer).
+          any(Engineer.name=='foo'))
+
+        or
+
+        query.join(Company.employees.of_type(Engineer)).
+          filter(Engineer.name=='foo')
+
+    - Preventive code against a potential lost-reference bug in
+      flush().
+
+    - Expressions used in filter(), filter_by() and others, when
+      they make usage of a clause generated from a relation
+      using the identity of a child object (e.g.,
+      filter(Parent.child==<somechild>)), evaluate the actual
+      primary key value of <somechild> at execution time so that
+      the autoflush step of the Query can complete, thereby
+      populating the PK value of <somechild> in the case that
+      <somechild> was pending.
+
+    - setting the relation()-level order by to a column in the
+      many-to-many "secondary" table will now work with eager
+      loading, previously the "order by" wasn't aliased against
+      the secondary table's alias.
+
+    - Synonyms riding on top of existing descriptors are now
+      full proxies to those descriptors.
+
+- dialects
+    - Invalid SQLite connection URLs now raise an error.
+
+    - postgres TIMESTAMP renders correctly [ticket:981]
+
+    - postgres PGArray is a "mutable" type by default; when used
+      with the ORM, mutable-style equality/ copy-on-write
+      techniques are used to test for changes.
+
+- extensions
+    - a new super-small "declarative" extension has been added,
+      which allows Table and mapper() configuration to take
+      place inline underneath a class declaration.  This
+      extension differs from ActiveMapper and Elixir in that it
+      does not redefine any SQLAlchemy semantics at all; literal
+      Column, Table and relation() constructs are used to define
+      the class behavior and table definition.
+
+0.4.3
+------
+- sql
+    - Added "schema.DDL", an executable free-form DDL statement.
+      DDLs can be executed in isolation or attached to Table or
+      MetaData instances and executed automatically when those
+      objects are created and/or dropped.
+
+    - Table columns and constraints can be overridden on a an
+      existing table (such as a table that was already reflected)
+      using the 'useexisting=True' flag, which now takes into
+      account the arguments passed along with it.
+
+    - Added a callable-based DDL events interface, adds hooks
+      before and after Tables and MetaData create and drop.
+
+    - Added generative where(<criterion>) method to delete() and
+      update() constructs which return a new object with criterion
+      joined to existing criterion via AND, just like
+      select().where().
+
+    - Added "ilike()" operator to column operations.  Compiles to
+      ILIKE on postgres, lower(x) LIKE lower(y) on all
+      others. [ticket:727]
+
+    - Added "now()" as a generic function; on SQLite, Oracle
+      and MSSQL compiles as "CURRENT_TIMESTAMP"; "now()" on
+      all others. [ticket:943]
+
+    - The startswith(), endswith(), and contains() operators now
+      concatenate the wildcard operator with the given operand in
+      SQL, i.e. "'%' || <bindparam>" in all cases, accept
+      text('something') operands properly [ticket:962]
+
+    - cast() accepts text('something') and other non-literal
+      operands properly [ticket:962]
+
+    - fixed bug in result proxy where anonymously generated
+      column labels would not be accessible using their straight
+      string name
+
+    - Deferrable constraints can now be defined.
+
+    - Added "autocommit=True" keyword argument to select() and
+      text(), as well as generative autocommit() method on
+      select(); for statements which modify the database through
+      some user-defined means other than the usual INSERT/UPDATE/
+      DELETE etc.  This flag will enable "autocommit" behavior
+      during execution if no transaction is in progress.
+      [ticket:915]
+
+    - The '.c.' attribute on a selectable now gets an entry for
+      every column expression in its columns clause.  Previously,
+      "unnamed" columns like functions and CASE statements weren't
+      getting put there.  Now they will, using their full string
+      representation if no 'name' is available.
+
+    - a CompositeSelect, i.e. any union(), union_all(),
+      intersect(), etc. now asserts that each selectable contains
+      the same number of columns.  This conforms to the
+      corresponding SQL requirement.
+
+    - The anonymous 'label' generated for otherwise unlabeled
+      functions and expressions now propagates outwards at compile
+      time for expressions like select([select([func.foo()])]).
+
+    - Building on the above ideas, CompositeSelects now build up
+      their ".c." collection based on the names present in the
+      first selectable only; corresponding_column() now works
+      fully for all embedded selectables.
+
+    - Oracle and others properly encode SQL used for defaults like
+      sequences, etc., even if no unicode idents are used since
+      identifier preparer may return a cached unicode identifier.
+
+    - Column and clause comparisons to datetime objects on the
+      left hand side of the expression now work (d < table.c.col).
+      (datetimes on the RHS have always worked, the LHS exception
+      is a quirk of the datetime implementation.)
+
+- orm
+    - Every Session.begin() must now be accompanied by a
+      corresponding commit() or rollback() unless the session is
+      closed with Session.close().  This also includes the begin()
+      which is implicit to a session created with
+      transactional=True.  The biggest change introduced here is
+      that when a Session created with transactional=True raises
+      an exception during flush(), you must call
+      Session.rollback() or Session.close() in order for that
+      Session to continue after an exception.
+
+    - Fixed merge() collection-doubling bug when merging transient
+      entities with backref'ed collections.  [ticket:961]
+
+    - merge(dont_load=True) does not accept transient entities,
+      this is in continuation with the fact that
+      merge(dont_load=True) does not accept any "dirty" objects
+      either.
+
+    - Added standalone "query" class attribute generated by a
+      scoped_session.  This provides MyClass.query without using
+      Session.mapper.  Use via:
+
+        MyClass.query = Session.query_property()
+
+    - The proper error message is raised when trying to access
+      expired instance attributes with no session present
+
+    - dynamic_loader() / lazy="dynamic" now accepts and uses
+      the order_by parameter in the same way in which it works
+      with relation().
+
+    - Added expire_all() method to Session.  Calls expire() for
+      all persistent instances.  This is handy in conjunction
+      with...
+
+    - Instances which have been partially or fully expired will
+      have their expired attributes populated during a regular
+      Query operation which affects those objects, preventing a
+      needless second SQL statement for each instance.
+
+    - Dynamic relations, when referenced, create a strong
+      reference to the parent object so that the query still has a
+      parent to call against even if the parent is only created
+      (and otherwise dereferenced) within the scope of a single
+      expression. [ticket:938]
+
+    - Added a mapper() flag "eager_defaults". When set to True,
+      defaults that are generated during an INSERT or UPDATE
+      operation are post-fetched immediately, instead of being
+      deferred until later.  This mimics the old 0.3 behavior.
+
+    - query.join() can now accept class-mapped attributes as
+      arguments. These can be used in place or in any combination
+      with strings.  In particular this allows construction of
+      joins to subclasses on a polymorphic relation, i.e.:
+
+        query(Company).join(['employees', Engineer.name])
+
+    - query.join() can also accept tuples of attribute name/some
+      selectable as arguments.  This allows construction of joins
+      *from* subclasses of a polymorphic relation, i.e.:
+
+        query(Company).\
+        join(
+          [('employees', people.join(engineer)), Engineer.name]
+        )
+
+    - General improvements to the behavior of join() in
+      conjunction with polymorphic mappers, i.e. joining from/to
+      polymorphic mappers and properly applying aliases.
+
+    - Fixed/improved behavior when a mapper determines the natural
+      "primary key" of a mapped join, it will more effectively
+      reduce columns which are equivalent via foreign key
+      relation.  This affects how many arguments need to be sent
+      to query.get(), among other things.  [ticket:933]
+
+    - The lazy loader can now handle a join condition where the
+      "bound" column (i.e. the one that gets the parent id sent as
+      a bind parameter) appears more than once in the join
+      condition.  Specifically this allows the common task of a
+      relation() which contains a parent-correlated subquery, such
+      as "select only the most recent child item". [ticket:946]
+
+    - Fixed bug in polymorphic inheritance where an incorrect
+      exception is raised when base polymorphic_on column does not
+      correspond to any columns within the local selectable of an
+      inheriting mapper more than one level deep
+
+    - Fixed bug in polymorphic inheritance which made it difficult
+      to set a working "order_by" on a polymorphic mapper.
+
+    - Fixed a rather expensive call in Query that was slowing down
+      polymorphic queries.
+
+    - "Passive defaults" and other "inline" defaults can now be
+      loaded during a flush() call if needed; in particular, this
+      allows constructing relations() where a foreign key column
+      references a server-side-generated, non-primary-key
+      column. [ticket:954]
+
+    - Additional Session transaction fixes/changes:
+        - Fixed bug with session transaction management: parent
+          transactions weren't started on the connection when
+          adding a connection to a nested transaction.
+
+        - session.transaction now always refers to the innermost
+          active transaction, even when commit/rollback are called
+          directly on the session transaction object.
+
+        - Two-phase transactions can now be prepared.
+
+        - When preparing a two-phase transaction fails on one
+          connection, all the connections are rolled back.
+
+        - session.close() didn't close all transactions when
+          nested transactions were used.
+
+        - rollback() previously erroneously set the current
+          transaction directly to the parent of the transaction
+          that could be rolled back to. Now it rolls back the next
+          transaction up that can handle it, but sets the current
+          transaction to it's parent and inactivates the
+          transactions in between. Inactive transactions can only
+          be rolled back or closed, any other call results in an
+          error.
+
+        - autoflush for commit() wasn't flushing for simple
+          subtransactions.
+
+        - unitofwork flush didn't close the failed transaction
+          when the session was not in a transaction and commiting
+          the transaction failed.
+
+    - Miscellaneous tickets: [ticket:940] [ticket:964]
+
+- general
+    - Fixed a variety of hidden and some not-so-hidden
+      compatibility issues for Python 2.3, thanks to new support
+      for running the full test suite on 2.3.
+
+    - Warnings are now issued as type exceptions.SAWarning.
+
+- dialects
+    - Better support for schemas in SQLite (linked in by ATTACH
+      DATABASE ... AS name).  In some cases in the past, schema
+      names were ommitted from generated SQL for SQLite.  This is
+      no longer the case.
+
+    - table_names on SQLite now picks up temporary tables as well.
+
+    - Auto-detect an unspecified MySQL ANSI_QUOTES mode during
+      reflection operations, support for changing the mode
+      midstream.  Manual mode setting is still required if no
+      reflection is used.
+
+    - Fixed reflection of TIME columns on SQLite.
+
+    - Finally added PGMacAddr type to postgres [ticket:580]
+
+    - Reflect the sequence associated to a PK field (typically
+      with a BEFORE INSERT trigger) under Firebird
+
+    - Oracle assembles the correct columns in the result set
+      column mapping when generating a LIMIT/OFFSET subquery,
+      allows columns to map properly to result sets even if
+      long-name truncation kicks in [ticket:941]
+
+    - MSSQL now includes EXEC in the _is_select regexp, which
+      should allow row-returning stored procedures to be used.
+
+    - MSSQL now includes an experimental implementation of
+      LIMIT/OFFSET using the ANSI SQL row_number() function, so it
+      requires MSSQL-2005 or higher. To enable the feature, add
+      "has_window_funcs" to the keyword arguments for connect, or
+      add "?has_window_funcs=1" to your dburi query arguments.
+
+- ext
+    - Changed ext.activemapper to use a non-transactional session
+      for the objectstore.
+
+    - Fixed output order of "['a'] + obj.proxied" binary operation
+      on association-proxied lists.
+
+0.4.2p3
+------
+- general
+    - sub version numbering scheme changed to suite
+      setuptools version number rules; easy_install -u
+      should now get this version over 0.4.2.
+
+- sql
+    - Text type is properly exported now and does not
+      raise a warning on DDL create; String types with no
+      length only raise warnings during CREATE TABLE
+      [ticket:912]
+
+    - new UnicodeText type is added, to specify an
+      encoded, unlengthed Text type
+
+    - fixed bug in union() so that select() statements
+      which don't derive from FromClause objects can be
+      unioned
+
+- orm
+    - fixed bug with session.dirty when using "mutable
+      scalars" (such as PickleTypes)
+
+    - added a more descriptive error message when flushing
+      on a relation() that has non-locally-mapped columns
+      in its primary or secondary join condition
+
+- dialects
+    - Fixed reflection of mysql empty string column
+      defaults.
+
+0.4.2b  (0.4.2p2)
+------
+- sql
+    - changed name of TEXT to Text since its a "generic"
+      type; TEXT name is deprecated until 0.5. The
+      "upgrading" behavior of String to Text when no
+      length is present is also deprecated until 0.5; will
+      issue a warning when used for CREATE TABLE
+      statements (String with no length for SQL expression
+      purposes is still fine) [ticket:912]
+
+    - generative select.order_by(None) / group_by(None)
+      was not managing to reset order by/group by
+      criterion, fixed [ticket:924]
+
+- orm
+    - suppressing *all* errors in
+      InstanceState.__cleanup() now.
+
+    - fixed an attribute history bug whereby assigning a
+      new collection to a collection-based attribute which
+      already had pending changes would generate incorrect
+      history [ticket:922]
+
+    - fixed delete-orphan cascade bug whereby setting the
+      same object twice to a scalar attribute could log it
+      as an orphan [ticket:925]
+
+    - Fixed cascades on a += assignment to a list-based
+      relation.
+
+    - synonyms can now be created against props that don't
+      exist yet, which are later added via add_property().
+      This commonly includes backrefs. (i.e. you can make
+      synonyms for backrefs without worrying about the
+      order of operations) [ticket:919]
+
+    - fixed bug which could occur with polymorphic "union"
+      mapper which falls back to "deferred" loading of
+      inheriting tables
+
+    - the "columns" collection on a mapper/mapped class
+      (i.e. 'c') is against the mapped table, not the
+      select_table in the case of polymorphic "union"
+      loading (this shouldn't be noticeable).
+
+- ext
+    - '+', '*', '+=' and '*=' support for association
+      proxied lists.
+
+- dialects
+    - mssql - narrowed down the test for "date"/"datetime"
+      in MSDate/ MSDateTime subclasses so that incoming
+      "datetime" objects don't get mis-interpreted as
+      "date" objects and vice versa, [ticket:923]
+
+0.4.2a   (0.4.2p1)
+------
+
+- orm
+    - fixed fairly critical bug whereby the same instance could be listed
+      more than once in the unitofwork.new collection; most typically
+      reproduced when using a combination of inheriting mappers and
+      ScopedSession.mapper, as the multiple __init__ calls per instance
+      could save() the object with distinct _state objects
+
+    - added very rudimentary yielding iterator behavior to Query.  Call
+      query.yield_per(<number of rows>) and evaluate the Query in an
+      iterative context; every collection of N rows will be packaged up
+      and yielded.  Use this method with extreme caution since it does
+      not attempt to reconcile eagerly loaded collections across
+      result batch boundaries, nor will it behave nicely if the same
+      instance occurs in more than one batch.  This means that an eagerly
+      loaded collection will get cleared out if it's referenced in more than
+      one batch, and in all cases attributes will be overwritten on instances
+      that occur in more than one batch.
+
+   - Fixed in-place set mutation operators for set collections and association
+     proxied sets. [ticket:920]
+
+- dialects
+    - Fixed the missing call to subtype result processor for the PGArray
+      type. [ticket:913]
+
+0.4.2
+-----
+- sql
+    - generic functions ! we introduce a database of known SQL functions, such
+      as current_timestamp, coalesce, and create explicit function objects
+      representing them. These objects have constrained argument lists, are
+      type aware, and can compile in a dialect-specific fashion. So saying
+      func.char_length("foo", "bar") raises an error (too many args),
+      func.coalesce(datetime.date(2007, 10, 5), datetime.date(2005, 10, 15))
+      knows that its return type is a Date. We only have a few functions
+      represented so far but will continue to add to the system [ticket:615]
+
+    - auto-reconnect support improved; a Connection can now automatically
+      reconnect after its underlying connection is invalidated, without
+      needing to connect() again from the engine.  This allows an ORM session
+      bound to a single Connection to not need a reconnect.
+      Open transactions on the Connection must be rolled back after an invalidation
+      of the underlying connection else an error is raised.  Also fixed
+      bug where disconnect detect was not being called for cursor(), rollback(),
+      or commit().
+
+    - added new flag to String and create_engine(),
+      assert_unicode=(True|False|'warn'|None). Defaults to `False` or `None` on
+      create_engine() and String, `'warn'` on the Unicode type. When `True`,
+      results in all unicode conversion operations raising an exception when a
+      non-unicode bytestring is passed as a bind parameter. 'warn' results
+      in a warning. It is strongly advised that all unicode-aware applications
+      make proper use of Python unicode objects (i.e. u'hello' and not 'hello')
+      so that data round trips accurately.
+
+    - generation of "unique" bind parameters has been simplified to use the same
+      "unique identifier" mechanisms as everything else.  This doesn't affect
+      user code, except any code that might have been hardcoded against the generated
+      names.  Generated bind params now have the form "<paramname>_<num>",
+      whereas before only the second bind of the same name would have this form.
+
+    - select().as_scalar() will raise an exception if the select does not have
+      exactly one expression in its columns clause.
+
+    - bindparam() objects themselves can be used as keys for execute(), i.e.
+      statement.execute({bind1:'foo', bind2:'bar'})
+
+    - added new methods to TypeDecorator, process_bind_param() and
+      process_result_value(), which automatically take advantage of the processing
+      of the underlying type.  Ideal for using with Unicode or Pickletype.
+      TypeDecorator should now be the primary way to augment the behavior of any
+      existing type including other TypeDecorator subclasses such as PickleType.
+
+    - selectables (and others) will issue a warning when two columns in
+      their exported columns collection conflict based on name.
+
+    - tables with schemas can still be used in sqlite, firebird,
+      schema name just gets dropped [ticket:890]
+
+    - changed the various "literal" generation functions to use an anonymous
+      bind parameter.  not much changes here except their labels now look
+      like ":param_1", ":param_2" instead of ":literal"
+
+    - column labels in the form "tablename.columname", i.e. with a dot, are now
+      supported.
+
+    - from_obj keyword argument to select() can be a scalar or a list.
+
+- orm
+   - a major behavioral change to collection-based backrefs: they no
+     longer trigger lazy loads !  "reverse" adds and removes
+     are queued up and are merged with the collection when it is
+     actually read from and loaded; but do not trigger a load beforehand.
+     For users who have noticed this behavior, this should be much more
+     convenient than using dynamic relations in some cases; for those who
+     have not, you might notice your apps using a lot fewer queries than
+     before in some situations. [ticket:871]
+
+   - mutable primary key support is added. primary key columns can be
+     changed freely, and the identity of the instance will change upon
+     flush. In addition, update cascades of foreign key referents (primary
+     key or not) along relations are supported, either in tandem with the
+     database's ON UPDATE CASCADE (required for DB's like Postgres) or
+     issued directly by the ORM in the form of UPDATE statements, by setting
+     the flag "passive_cascades=False".
+
+   - inheriting mappers now inherit the MapperExtensions of their parent
+     mapper directly, so that all methods for a particular MapperExtension
+     are called for subclasses as well.  As always, any MapperExtension
+     can return either EXT_CONTINUE to continue extension processing
+     or EXT_STOP to stop processing.  The order of mapper resolution is:
+     <extensions declared on the classes mapper> <extensions declared on the
+     classes' parent mapper> <globally declared extensions>.
+
+     Note that if you instantiate the same extension class separately
+     and then apply it individually for two mappers in the same inheritance
+     chain, the extension will be applied twice to the inheriting class,
+     and each method will be called twice.
+
+     To apply a mapper extension explicitly to each inheriting class but
+     have each method called only once per operation, use the same
+     instance of the extension for both mappers.
+     [ticket:490]
+
+   - MapperExtension.before_update() and after_update() are now called
+     symmetrically; previously, an instance that had no modified column
+     attributes (but had a relation() modification) could be called with
+     before_update() but not after_update() [ticket:907]
+
+   - columns which are missing from a Query's select statement
+     now get automatically deferred during load.
+
+   - mapped classes which extend "object" and do not provide an
+     __init__() method will now raise TypeError if non-empty *args
+     or **kwargs are present at instance construction time (and are
+     not consumed by any extensions such as the scoped_session mapper),
+     consistent with the behavior of normal Python classes [ticket:908]
+
+   - fixed Query bug when filter_by() compares a relation against None
+     [ticket:899]
+
+   - improved support for pickling of mapped entities.  Per-instance
+     lazy/deferred/expired callables are now serializable so that
+     they serialize and deserialize with _state.
+
+   - new synonym() behavior: an attribute will be placed on the mapped
+     class, if one does not exist already, in all cases. if a property
+     already exists on the class, the synonym will decorate the property
+     with the appropriate comparison operators so that it can be used in in
+     column expressions just like any other mapped attribute (i.e. usable in
+     filter(), etc.) the "proxy=True" flag is deprecated and no longer means
+     anything. Additionally, the flag "map_column=True" will automatically
+     generate a ColumnProperty corresponding to the name of the synonym,
+     i.e.: 'somename':synonym('_somename', map_column=True) will map the
+     column named 'somename' to the attribute '_somename'. See the example
+     in the mapper docs. [ticket:801]
+
+   - Query.select_from() now replaces all existing FROM criterion with
+     the given argument; the previous behavior of constructing a list
+     of FROM clauses was generally not useful as is required
+     filter() calls to create join criterion, and new tables introduced
+     within filter() already add themselves to the FROM clause.  The
+     new behavior allows not just joins from the main table, but select
+     statements as well.  Filter criterion, order bys, eager load
+     clauses will be "aliased" against the given statement.
+
+   - this month's refactoring of attribute instrumentation changes
+     the "copy-on-load" behavior we've had since midway through 0.3
+     with "copy-on-modify" in most cases.  This takes a sizable chunk
+     of latency out of load operations and overall does less work
+     as only attributes which are actually modified get their
+     "committed state" copied.  Only "mutable scalar" attributes
+     (i.e. a pickled object or other mutable item), the reason for
+     the copy-on-load change in the first place, retain the old
+     behavior.
+
+   - a slight behavioral change to attributes is, del'ing an attribute
+     does *not* cause the lazyloader of that attribute to fire off again;
+     the "del" makes the effective value of the attribute "None".  To
+     re-trigger the "loader" for an attribute, use
+     session.expire(instance, [attrname]).
+
+   - query.filter(SomeClass.somechild == None), when comparing
+     a many-to-one property to None, properly generates "id IS NULL"
+     including that the NULL is on the right side.
+
+   - query.order_by() takes into account aliased joins, i.e.
+     query.join('orders', aliased=True).order_by(Order.id)
+
+   - eagerload(), lazyload(), eagerload_all() take an optional
+     second class-or-mapper argument, which will select the mapper
+     to apply the option towards.  This can select among other
+     mappers which were added using add_entity().
+
+   - eagerloading will work with mappers added via add_entity().
+
+   - added "cascade delete" behavior to "dynamic" relations just like
+     that of regular relations.  if passive_deletes flag (also just added)
+     is not set, a delete of the parent item will trigger a full load of
+     the child items so that they can be deleted or updated accordingly.
+
+   - also with dynamic, implemented correct count() behavior as well
+     as other helper methods.
+
+   - fix to cascades on polymorphic relations, such that cascades
+     from an object to a polymorphic collection continue cascading
+     along the set of attributes specific to each element in the collection.
+
+   - query.get() and query.load() do not take existing filter or other
+     criterion into account; these methods *always* look up the given id
+     in the database or return the current instance from the identity map,
+     disregarding any existing filter, join, group_by or other criterion
+     which has been configured. [ticket:893]
+
+   - added support for version_id_col in conjunction with inheriting mappers.
+     version_id_col is typically set on the base mapper in an inheritance
+     relationship where it takes effect for all inheriting mappers.
+     [ticket:883]
+
+   - relaxed rules on column_property() expressions having labels; any
+     ColumnElement is accepted now, as the compiler auto-labels non-labeled
+     ColumnElements now.  a selectable, like a select() statement, still
+     requires conversion to ColumnElement via as_scalar() or label().
+
+   - fixed backref bug where you could not del instance.attr if attr
+     was None
+
+   - several ORM attributes have been removed or made private:
+     mapper.get_attr_by_column(), mapper.set_attr_by_column(),
+     mapper.pks_by_table, mapper.cascade_callable(),
+     MapperProperty.cascade_callable(), mapper.canload(),
+     mapper.save_obj(), mapper.delete_obj(), mapper._mapper_registry,
+     attributes.AttributeManager
+
+   - Assigning an incompatible collection type to a relation attribute now
+     raises TypeError instead of sqlalchemy's ArgumentError.
+
+   - Bulk assignment of a MappedCollection now raises an error if a key in the
+     incoming dictionary does not match the key that the collection's keyfunc
+     would use for that value. [ticket:886]
+
+   - Custom collections can now specify a @converter method to translate
+     objects used in "bulk" assignment into a stream of values, as in::
+
+        obj.col = [newval1, newval2]
+        # or
+        obj.dictcol = {'foo': newval1, 'bar': newval2}
+
+     The MappedCollection uses this hook to ensure that incoming key/value
+     pairs are sane from the collection's perspective.
+
+   - fixed endless loop issue when using lazy="dynamic" on both
+     sides of a bi-directional relationship [ticket:872]
+
+   - more fixes to the LIMIT/OFFSET aliasing applied with Query + eagerloads,
+     in this case when mapped against a select statement [ticket:904]
+
+   - fix to self-referential eager loading such that if the same mapped
+     instance appears in two or more distinct sets of columns in the same
+     result set, its eagerly loaded collection will be populated regardless
+     of whether or not all of the rows contain a set of "eager" columns for
+     that collection.  this would also show up as a KeyError when fetching
+     results with join_depth turned on.
+
+   - fixed bug where Query would not apply a subquery to the SQL when LIMIT
+     was used in conjunction with an inheriting mapper where the eager
+     loader was only in the parent mapper.
+
+   - clarified the error message which occurs when you try to update()
+     an instance with the same identity key as an instance already present
+     in the session.
+
+   - some clarifications and fixes to merge(instance, dont_load=True).
+     fixed bug where lazy loaders were getting disabled on returned instances.
+     Also, we currently do not support merging an instance which has uncommitted
+     changes on it, in the case that dont_load=True is used....this will
+     now raise an error.  This is due to complexities in merging the
+     "committed state" of the given instance to correctly correspond to the
+     newly copied instance, as well as other modified state.
+     Since the use case for dont_load=True is caching, the given instances
+     shouldn't have any uncommitted changes on them anyway.
+     We also copy the instances over without using any events now, so that
+     the 'dirty' list on the new session remains unaffected.
+
+   - fixed bug which could arise when using session.begin_nested() in conjunction
+     with more than one level deep of enclosing session.begin() statements
+
+   - fixed session.refresh() with instance that has custom entity_name
+     [ticket:914]
+
+- dialects
+
+   - sqlite SLDate type will not erroneously render "microseconds" portion
+     of a datetime or time object.
+
+   - oracle
+      - added disconnect detection support for Oracle
+      - some cleanup to binary/raw types so that cx_oracle.LOB is detected
+        on an ad-hoc basis [ticket:902]
+
+   - MSSQL
+      - PyODBC no longer has a global "set nocount on".
+      - Fix non-identity integer PKs on autload [ticket:824]
+      - Better support for convert_unicode [ticket:839]
+      - Less strict date conversion for pyodbc/adodbapi [ticket:842]
+      - Schema-qualified tables / autoload [ticket:901]
+
+   - Firebird backend
+
+     - does properly reflect domains (partially fixing [ticket:410]) and
+       PassiveDefaults
+
+     - reverted to use default poolclass (was set to SingletonThreadPool in
+       0.4.0 [3562] for test purposes)
+
+     - map func.length() to 'char_length' (easily overridable with the UDF
+       'strlen' on old versions of Firebird)
+
+
+0.4.1
+-----
+
+- sql
+
+  - the "shortname" keyword parameter on bindparam() has been
+    deprecated.
+
+  - Added contains operator (generates a "LIKE %<other>%" clause).
+
+  - anonymous column expressions are automatically labeled.
+    e.g. select([x* 5]) produces "SELECT x * 5 AS anon_1".
+    This allows the labelname to be present in the cursor.description
+    which can then be appropriately matched to result-column processing
+    rules. (we can't reliably use positional tracking for result-column
+    matches since text() expressions may represent multiple columns).
+
+  - operator overloading is now controlled by TypeEngine objects - the
+    one built-in operator overload so far is String types overloading
+    '+' to be the string concatenation operator.
+    User-defined types can also define their own operator overloading
+    by overriding the adapt_operator(self, op) method.
+
+  - untyped bind parameters on the right side of a binary expression
+    will be assigned the type of the left side of the operation, to better
+    enable the appropriate bind parameter processing to take effect
+    [ticket:819]
+
+  - Removed regular expression step from most statement compilations.
+    Also fixes [ticket:833]
+
+  - Fixed empty (zero column) sqlite inserts, allowing inserts on
+    autoincrementing single column tables.
+
+  - Fixed expression translation of text() clauses; this repairs various
+    ORM scenarios where literal text is used for SQL expressions
+
+  - Removed ClauseParameters object; compiled.params returns a regular
+    dictionary now, as well as result.last_inserted_params() /
+    last_updated_params().
+
+  - Fixed INSERT statements w.r.t. primary key columns that have
+    SQL-expression based default generators on them; SQL expression
+    executes inline as normal but will not trigger a "postfetch" condition
+    for the column, for those DB's who provide it via cursor.lastrowid
+
+  - func. objects can be pickled/unpickled [ticket:844]
+
+  - rewrote and simplified the system used to "target" columns across
+    selectable expressions.  On the SQL side this is represented by the
+    "corresponding_column()" method. This method is used heavily by the ORM
+    to "adapt" elements of an expression to similar, aliased expressions,
+    as well as to target result set columns originally bound to a
+    table or selectable to an aliased, "corresponding" expression.  The new
+    rewrite features completely consistent and accurate behavior.
+
+  - Added a field ("info") for storing arbitrary data on schema items
+    [ticket:573]
+
+  - The "properties" collection on Connections has been renamed "info" to
+    match schema's writable collections.  Access is still available via
+    the "properties" name until 0.5.
+
+  - fixed the close() method on Transaction when using strategy='threadlocal'
+
+  - fix to compiled bind parameters to not mistakenly populate None
+    [ticket:853]
+
+  - <Engine|Connection>._execute_clauseelement becomes a public method
+    Connectable.execute_clauseelement
+
+- orm
+  - eager loading with LIMIT/OFFSET applied no longer adds the primary
+    table joined to a limited subquery of itself; the eager loads now
+    join directly to the subquery which also provides the primary table's
+    columns to the result set.  This eliminates a JOIN from all eager loads
+    with LIMIT/OFFSET.  [ticket:843]
+
+  - session.refresh() and session.expire() now support an additional argument
+    "attribute_names", a list of individual attribute keynames to be refreshed
+    or expired, allowing partial reloads of attributes on an already-loaded
+    instance. [ticket:802]
+
+  - added op() operator to instrumented attributes; i.e.
+    User.name.op('ilike')('%somename%') [ticket:767]
+
+  - Mapped classes may now define __eq__, __hash__, and __nonzero__ methods
+    with arbitrary semantics.  The orm now handles all mapped instances on
+    an identity-only basis. (e.g. 'is' vs '==') [ticket:676]
+
+  - the "properties" accessor on Mapper is removed; it now throws an informative
+    exception explaining the usage of mapper.get_property() and
+    mapper.iterate_properties
+
+  - added having() method to Query, applies HAVING to the generated statement
+    in the same way as filter() appends to the WHERE clause.
+
+  - The behavior of query.options() is now fully based on paths, i.e. an
+    option such as eagerload_all('x.y.z.y.x') will apply eagerloading to
+    only those paths, i.e. and not 'x.y.x'; eagerload('children.children')
+    applies only to exactly two-levels deep, etc. [ticket:777]
+
+  - PickleType will compare using `==` when set up with mutable=False,
+    and not the `is` operator.  To use `is` or any other comparator, send
+    in a custom comparison function using PickleType(comparator=my_custom_comparator).
+
+  - query doesn't throw an error if you use distinct() and an order_by()
+    containing UnaryExpressions (or other) together [ticket:848]
+
+  - order_by() expressions from joined tables are properly added to columns
+    clause when using distinct() [ticket:786]
+
+  - fixed error where Query.add_column() would not accept a class-bound
+    attribute as an argument; Query also raises an error if an invalid
+    argument was sent to add_column() (at instances() time) [ticket:858]
+
+  - added a little more checking for garbage-collection dereferences in
+    InstanceState.__cleanup() to reduce "gc ignored" errors on app
+    shutdown
+
+  - The session API has been solidified:
+
+    - It's an error to session.save() an object which is already
+      persistent [ticket:840]
+
+    - It's an error to session.delete() an object which is *not*
+      persistent.
+
+    - session.update() and session.delete() raise an error when updating
+      or deleting an instance that is already in the session with a
+      different identity.
+
+    - The session checks more carefully when determining "object X already
+      in another session"; e.g. if you pickle a series of objects and
+      unpickle (i.e. as in a Pylons HTTP session or similar), they can go
+      into a new session without any conflict
+
+    - merge() includes a keyword argument "dont_load=True".  setting this
+      flag will cause the merge operation to not load any data from the
+      database in response to incoming detached objects, and will accept
+      the incoming detached object as though it were already present in
+      that session.  Use this to merge detached objects from external
+      caching systems into the session.
+
+  - Deferred column attributes no longer trigger a load operation when the
+    attribute is assigned to.  In those cases, the newly assigned value
+    will be present in the flushes' UPDATE statement unconditionally.
+
+  - Fixed a truncation error when re-assigning a subset of a collection
+    (obj.relation = obj.relation[1:]) [ticket:834]
+
+  - De-cruftified backref configuration code, backrefs which step on
+    existing properties now raise an error [ticket:832]
+
+  - Improved behavior of add_property() etc., fixed [ticket:831] involving
+    synonym/deferred.
+
+  - Fixed clear_mappers() behavior to better clean up after itself.
+
+  - Fix to "row switch" behavior, i.e. when an INSERT/DELETE is combined
+    into a single UPDATE; many-to-many relations on the parent object
+    update properly.  [ticket:841]
+
+  - Fixed __hash__ for association proxy- these collections are unhashable,
+    just like their mutable Python counterparts.
+
+  - Added proxying of save_or_update, __contains__ and __iter__ methods for
+    scoped sessions.
+
+  - fixed very hard-to-reproduce issue where by the FROM clause of Query
+    could get polluted by certain generative calls [ticket:852]
+
+- dialects
+
+  - Added experimental support for MaxDB (versions >= 7.6.03.007 only).
+
+  - oracle will now reflect "DATE" as an OracleDateTime column, not
+    OracleDate
+
+  - added awareness of schema name in oracle table_names() function,
+    fixes metadata.reflect(schema='someschema') [ticket:847]
+
+  - MSSQL anonymous labels for selection of functions made deterministic
+
+  - sqlite will reflect "DECIMAL" as a numeric column.
+
+  - Made access dao detection more reliable [ticket:828]
+
+  - Renamed the Dialect attribute 'preexecute_sequences' to
+    'preexecute_pk_sequences'.  An attribute porxy is in place for
+    out-of-tree dialects using the old name.
+
+  - Added test coverage for unknown type reflection. Fixed sqlite/mysql
+    handling of type reflection for unknown types.
+
+  - Added REAL for mysql dialect (for folks exploiting the
+    REAL_AS_FLOAT sql mode).
+
+  - mysql Float, MSFloat and MSDouble constructed without arguments
+    now produce no-argument DDL, e.g.'FLOAT'.
+
+- misc
+
+  - Removed unused util.hash().
+
+
+0.4.0
+-----
+
+- (see 0.4.0beta1 for the start of major changes against 0.3,
+  as well as http://www.sqlalchemy.org/trac/wiki/WhatsNewIn04 )
+
+- Added initial Sybase support (mxODBC so far) [ticket:785]
+
+- Added partial index support for PostgreSQL. Use the postgres_where keyword
+  on the Index.
+
+- string-based query param parsing/config file parser understands
+  wider range of string values for booleans [ticket:817]
+
+- backref remove object operation doesn't fail if the other-side
+  collection doesn't contain the item, supports noload collections
+  [ticket:813]
+
+- removed __len__ from "dynamic" collection as it would require issuing
+  a SQL "count()" operation, thus forcing all list evaluations to issue
+  redundant SQL [ticket:818]
+
+- inline optimizations added to locate_dirty() which can greatly speed up
+  repeated calls to flush(), as occurs with autoflush=True [ticket:816]
+
+- The IdentifierPreprarer's _requires_quotes test is now regex based.  Any
+  out-of-tree dialects that provide custom sets of legal_characters or
+  illegal_initial_characters will need to move to regexes or override
+  _requires_quotes.
+
+- Firebird has supports_sane_rowcount and supports_sane_multi_rowcount set
+  to False due to ticket #370 (right way).
+
+- Improvements and fixes on Firebird reflection:
+  . FBDialect now mimics OracleDialect, regarding case-sensitivity of TABLE and
+    COLUMN names (see 'case_sensitive remotion' topic on this current file).
+  . FBDialect.table_names() doesn't bring system tables (ticket:796).
+  . FB now reflects Column's nullable property correctly.
+
+- Fixed SQL compiler's awareness of top-level column labels as used
+  in result-set processing; nested selects which contain the same column
+  names don't affect the result or conflict with result-column metadata.
+
+- query.get() and related functions (like many-to-one lazyloading)
+  use compile-time-aliased bind parameter names, to prevent
+  name conflicts with bind parameters that already exist in the
+  mapped selectable.
+
+- Fixed three- and multi-level select and deferred inheritance loading
+  (i.e. abc inheritance with no select_table), [ticket:795]
+
+- Ident passed to id_chooser in shard.py always a list.
+
+- The no-arg ResultProxy._row_processor() is now the class attribute
+  `_process_row`.
+
+- Added support for returning values from inserts and updates for
+  PostgreSQL 8.2+. [ticket:797]
+
+- PG reflection, upon seeing the default schema name being used explicitly
+  as the "schema" argument in a Table, will assume that this is the the
+  user's desired convention, and will explicitly set the "schema" argument
+  in foreign-key-related reflected tables, thus making them match only
+  with Table constructors that also use the explicit "schema" argument
+  (even though its the default schema).
+  In other words, SA assumes the user is being consistent in this usage.
+
+- fixed sqlite reflection of BOOL/BOOLEAN [ticket:808]
+
+- Added support for UPDATE with LIMIT on mysql.
+
+- null foreign key on a m2o doesn't trigger a lazyload [ticket:803]
+
+- oracle does not implicitly convert to unicode for non-typed result
+  sets (i.e. when no TypeEngine/String/Unicode type is even being used;
+  previously it was detecting DBAPI types and converting regardless).
+  should fix [ticket:800]
+
+- fix to anonymous label generation of long table/column names [ticket:806]
+
+- Firebird dialect now uses SingletonThreadPool as poolclass.
+
+- Firebird now uses dialect.preparer to format sequences names
+
+- Fixed breakage with postgres and multiple two-phase transactions. Two-phase
+  commits and and rollbacks didn't automatically end up with a new transaction
+  as the usual dbapi commits/rollbacks do. [ticket:810]
+
+- Added an option to the _ScopedExt mapper extension to not automatically
+  save new objects to session on object initialization.
+
+- fixed Oracle non-ansi join syntax
+
+- PickleType and Interval types (on db not supporting it natively) are now
+  slightly faster.
+
+- Added Float and Time types to Firebird (FBFloat and FBTime). Fixed
+  BLOB SUB_TYPE for TEXT and Binary types.
+
+- Changed the API for the in_ operator. in_() now accepts a single argument
+  that is a sequence of values or a selectable. The old API of passing in
+  values as varargs still works but is deprecated.
+
+
+0.4.0beta6
+----------
+
+- The Session identity map is now *weak referencing* by default, use
+  weak_identity_map=False to use a regular dict.  The weak dict we are using
+  is customized to detect instances which are "dirty" and maintain a
+  temporary strong reference to those instances until changes are flushed.
+
+- Mapper compilation has been reorganized such that most compilation occurs
+  upon mapper construction.  This allows us to have fewer calls to
+  mapper.compile() and also to allow class-based properties to force a
+  compilation (i.e. User.addresses == 7 will compile all mappers; this is
+  [ticket:758]).  The only caveat here is that an inheriting mapper now
+  looks for its inherited mapper upon construction; so mappers within
+  inheritance relationships need to be constructed in inheritance order
+  (which should be the normal case anyway).
+
+- added "FETCH" to the keywords detected by Postgres to indicate a
+  result-row holding statement (i.e. in addition to "SELECT").
+
+- Added full list of SQLite reserved keywords so that they get escaped
+  properly.
+
+- Tightened up the relationship between the Query's generation of "eager
+  load" aliases, and Query.instances() which actually grabs the eagerly
+  loaded rows.  If the aliases were not specifically generated for that
+  statement by EagerLoader, the EagerLoader will not take effect when the
+  rows are fetched.  This prevents columns from being grabbed accidentally
+  as being part of an eager load when they were not meant for such, which
+  can happen with textual SQL as well as some inheritance situations.  It's
+  particularly important since the "anonymous aliasing" of columns uses
+  simple integer counts now to generate labels.
+
+- Removed "parameters" argument from clauseelement.compile(), replaced with
+  "column_keys".  The parameters sent to execute() only interact with the
+  insert/update statement compilation process in terms of the column names
+  present but not the values for those columns.  Produces more consistent
+  execute/executemany behavior, simplifies things a bit internally.
+
+- Added 'comparator' keyword argument to PickleType.  By default, "mutable"
+  PickleType does a "deep compare" of objects using their dumps()
+  representation.  But this doesn't work for dictionaries.  Pickled objects
+  which provide an adequate __eq__() implementation can be set up with
+  "PickleType(comparator=operator.eq)" [ticket:560]
+
+- Added session.is_modified(obj) method; performs the same "history"
+  comparison operation as occurs within a flush operation; setting
+  include_collections=False gives the same result as is used when the flush
+  determines whether or not to issue an UPDATE for the instance's row.
+
+- Added "schema" argument to Sequence; use this with Postgres /Oracle when
+  the sequence is located in an alternate schema.  Implements part of
+  [ticket:584], should fix [ticket:761].
+
+- Fixed reflection of the empty string for mysql enums.
+
+- Changed MySQL dialect to use the older LIMIT <offset>, <limit> syntax
+  instead of LIMIT <l> OFFSET <o> for folks using 3.23. [ticket:794]
+
+- Added 'passive_deletes="all"' flag to relation(), disables all nulling-out
+  of foreign key attributes during a flush where the parent object is
+  deleted.
+
+- Column defaults and onupdates, executing inline, will add parenthesis for
+  subqueries and other parenthesis-requiring expressions
+
+- The behavior of String/Unicode types regarding that they auto-convert to
+  TEXT/CLOB when no length is present now occurs *only* for an exact type of
+  String or Unicode with no arguments.  If you use VARCHAR or NCHAR
+  (subclasses of String/Unicode) with no length, they will be interpreted by
+  the dialect as VARCHAR/NCHAR; no "magic" conversion happens there.  This
+  is less surprising behavior and in particular this helps Oracle keep
+  string-based bind parameters as VARCHARs and not CLOBs [ticket:793].
+
+- Fixes to ShardedSession to work with deferred columns [ticket:771].
+
+- User-defined shard_chooser() function must accept "clause=None" argument;
+  this is the ClauseElement passed to session.execute(statement) and can be
+  used to determine correct shard id (since execute() doesn't take an
+  instance.)
+
+- Adjusted operator precedence of NOT to match '==' and others, so that
+  ~(x <operator> y) produces NOT (x <op> y), which is better compatible
+  with older MySQL versions. [ticket:764].  This doesn't apply to "~(x==y)"
+  as it does in 0.3 since ~(x==y) compiles to "x != y", but still applies
+  to operators like BETWEEN.
+
+- Other tickets: [ticket:768], [ticket:728], [ticket:779], [ticket:757]
+
+0.4.0beta5
+----------
+
+- Connection pool fixes; the better performance of beta4 remains but fixes
+  "connection overflow" and other bugs which were present (like
+  [ticket:754]).
+
+- Fixed bugs in determining proper sync clauses from custom inherit
+  conditions. [ticket:769]
+
+- Extended 'engine_from_config' coercion for QueuePool size / overflow.
+  [ticket:763]
+
+- mysql views can be reflected again. [ticket:748]
+
+- AssociationProxy can now take custom getters and setters.
+
+- Fixed malfunctioning BETWEEN in orm queries.
+
+- Fixed OrderedProperties pickling [ticket:762]
+
+- SQL-expression defaults and sequences now execute "inline" for all
+  non-primary key columns during an INSERT or UPDATE, and for all columns
+  during an executemany()-style call. inline=True flag on any insert/update
+  statement also forces the same behavior with a single execute().
+  result.postfetch_cols() is a collection of columns for which the previous
+  single insert or update statement contained a SQL-side default expression.
+
+- Fixed PG executemany() behavior, [ticket:759]
+
+- postgres reflects tables with autoincrement=False for primary key columns
+  which have no defaults.
+
+- postgres no longer wraps executemany() with individual execute() calls,
+  instead favoring performance.  "rowcount"/"concurrency" checks with
+  deleted items (which use executemany) are disabled with PG since psycopg2
+  does not report proper rowcount for executemany().
+
+- Tickets fixed:
+
+  - [ticket:742]
+  - [ticket:748]
+  - [ticket:760]
+  - [ticket:762]
+  - [ticket:763]
+
+0.4.0beta4
+----------
+
+- Tidied up what ends up in your namespace when you 'from sqlalchemy import *':
+
+  - 'table' and 'column' are no longer imported.  They remain available by
+    direct reference (as in 'sql.table' and 'sql.column') or a glob import
+    from the sql package.  It was too easy to accidentally use a
+    sql.expressions.table instead of schema.Table when just starting out
+    with SQLAlchemy, likewise column.
+
+  - Internal-ish classes like ClauseElement, FromClause, NullTypeEngine,
+    etc., are also no longer imported into your namespace
+
+  - The 'Smallinteger' compatiblity name (small i!) is no longer imported,
+    but remains in schema.py for now.  SmallInteger (big I!) is still
+    imported.
+
+- The connection pool uses a "threadlocal" strategy internally to return
+  the same connection already bound to a thread, for "contextual" connections;
+  these are the connections used when you do a "connectionless" execution
+  like insert().execute().  This is like a "partial" version of the
+  "threadlocal" engine strategy but without the thread-local transaction part
+  of it.  We're hoping it reduces connection pool overhead as well as
+  database usage.  However, if it proves to impact stability in a negative way,
+  we'll roll it right back.
+
+- Fix to bind param processing such that "False" values (like blank strings)
+  still get processed/encoded.
+
+- Fix to select() "generative" behavior, such that calling column(),
+  select_from(), correlate(), and with_prefix() does not modify the
+  original select object [ticket:752]
+
+- Added a "legacy" adapter to types, such that user-defined TypeEngine
+  and TypeDecorator classes which define convert_bind_param() and/or
+  convert_result_value() will continue to function.  Also supports
+  calling the super() version of those methods.
+
+- Added session.prune(), trims away instances cached in a session that
+  are no longer referenced elsewhere. (A utility for strong-ref
+  identity maps).
+
+- Added close() method to Transaction.  Closes out a transaction using
+  rollback if it's the outermost transaction, otherwise just ends
+  without affecting the outer transaction.
+
+- Transactional and non-transactional Session integrates better with
+  bound connection; a close() will ensure that connection
+  transactional state is the same as that which existed on it before
+  being bound to the Session.
+
+- Modified SQL operator functions to be module-level operators,
+  allowing SQL expressions to be pickleable. [ticket:735]
+
+- Small adjustment to mapper class.__init__ to allow for Py2.6
+  object.__init__() behavior.
+
+- Fixed 'prefix' argument for select()
+
+- Connection.begin() no longer accepts nested=True, this logic is now
+  all in begin_nested().
+
+- Fixes to new "dynamic" relation loader involving cascades
+
+- Tickets fixed:
+
+  - [ticket:735]
+  - [ticket:752]
+
+0.4.0beta3
+----------
+
+- SQL types optimization:
+
+  - New performance tests show a combined mass-insert/mass-select test as
+    having 68% fewer function calls than the same test run against 0.3.
+
+  - General performance improvement of result set iteration is around 10-20%.
+
+  - In types.AbstractType, convert_bind_param() and convert_result_value()
+    have migrated to callable-returning bind_processor() and
+    result_processor() methods.  If no callable is returned, no pre/post
+    processing function is called.
+
+  - Hooks added throughout base/sql/defaults to optimize the calling of bind
+    aram/result processors so that method call overhead is minimized.
+
+  - Support added for executemany() scenarios such that unneeded "last row id"
+    logic doesn't kick in, parameters aren't excessively traversed.
+
+- Added 'inherit_foreign_keys' arg to mapper().
+
+- Added support for string date passthrough in sqlite.
+
+- Tickets fixed:
+
+  - [ticket:738]
+  - [ticket:739]
+  - [ticket:743]
+  - [ticket:744]
+
+0.4.0beta2
+----------
+
+- mssql improvements.
+
+- oracle improvements.
+
+- Auto-commit after LOAD DATA INFILE for mysql.
+
+- A rudimental SessionExtension class has been added, allowing user-defined
+  functionality to take place at flush(), commit(), and rollback() boundaries.
+
+- Added engine_from_config() function for helping to create_engine() from an
+  .ini style config.
+
+- base_mapper() becomes a plain attribute.
+
+- session.execute() and scalar() can search for a Table with which to bind from
+  using the given ClauseElement.
+
+- Session automatically extrapolates tables from mappers with binds, also uses
+  base_mapper so that inheritance hierarchies bind automatically.
+
+- Moved ClauseVisitor traversal back to inlined non-recursive.
+
+- Tickets fixed:
+
+  - [ticket:730]
+  - [ticket:732]
+  - [ticket:733]
+  - [ticket:734]
+
+0.4.0beta1
+----------
+
+- orm
+
+  - Speed! Along with recent speedups to ResultProxy, total number of function
+    calls significantly reduced for large loads.
+
+  - test/perf/masseagerload.py reports 0.4 as having the fewest number of
+    function calls across all SA versions (0.1, 0.2, and 0.3).
+
+  - New collection_class api and implementation [ticket:213]. Collections are
+    now instrumented via decorations rather than proxying.  You can now have
+    collections that manage their own membership, and your class instance will
+    be directly exposed on the relation property.  The changes are transparent
+    for most users.
+
+    - InstrumentedList (as it was) is removed, and relation properties no
+      longer have 'clear()', '.data', or any other added methods beyond those
+      provided by the collection type. You are free, of course, to add them to
+      a custom class.
+
+    - __setitem__-like assignments now fire remove events for the existing
+      value, if any.
+
+    - dict-likes used as collection classes no longer need to change __iter__
+      semantics- itervalues() is used by default instead. This is a backwards
+      incompatible change.
+
+    - Subclassing dict for a mapped collection is no longer needed in most
+      cases. orm.collections provides canned implementations that key objects
+      by a specified column or a custom function of your choice.
+
+    - Collection assignment now requires a compatible type- assigning None to
+      clear a collection or assigning a list to a dict collection will now
+      raise an argument error.
+
+    - AttributeExtension moved to interfaces, and .delete is now .remove The
+      event method signature has also been swapped around.
+
+  - Major overhaul for Query:
+
+    - All selectXXX methods are deprecated.  Generative methods are now the
+      standard way to do things, i.e. filter(), filter_by(), all(), one(),
+      etc.  Deprecated methods are docstring'ed with their new replacements.
+
+    - Class-level properties are now usable as query elements... no more
+      '.c.'!  "Class.c.propname" is now superceded by "Class.propname".  All
+      clause operators are supported, as well as higher level operators such
+      as Class.prop==<some instance> for scalar attributes,
+      Class.prop.contains(<some instance>) and Class.prop.any(<some
+      expression>) for collection-based attributes (all are also
+      negatable).  Table-based column expressions as well as columns mounted
+      on mapped classes via 'c' are of course still fully available and can be
+      freely mixed with the new attributes.  [ticket:643]
+
+    - Removed ancient query.select_by_attributename() capability.
+
+    - The aliasing logic used by eager loading has been generalized, so that
+      it also adds full automatic aliasing support to Query.  It's no longer
+      necessary to create an explicit Alias to join to the same tables
+      multiple times; *even for self-referential relationships*.
+
+      - join() and outerjoin() take arguments "aliased=True".  Yhis causes
+        their joins to be built on aliased tables; subsequent calls to
+        filter() and filter_by() will translate all table expressions (yes,
+        real expressions using the original mapped Table) to be that of the
+        Alias for the duration of that join() (i.e. until reset_joinpoint() or
+        another join() is called).
+
+      - join() and outerjoin() take arguments "id=<somestring>".  When used
+        with "aliased=True", the id can be referenced by add_entity(cls,
+        id=<somestring>) so that you can select the joined instances even if
+        they're from an alias.
+
+      - join() and outerjoin() now work with self-referential relationships!
+        Using "aliased=True", you can join as many levels deep as desired,
+        i.e. query.join(['children', 'children'], aliased=True); filter
+        criterion will be against the rightmost joined table
+
+    - Added query.populate_existing(), marks the query to reload all
+      attributes and collections of all instances touched in the query,
+      including eagerly-loaded entities.  [ticket:660]
+
+    - Added eagerload_all(), allows eagerload_all('x.y.z') to specify eager
+      loading of all properties in the given path.
+
+  - Major overhaul for Session:
+
+    - New function which "configures" a session called "sessionmaker()".  Send
+      various keyword arguments to this function once, returns a new class
+      which creates a Session against that stereotype.
+
+    - SessionTransaction removed from "public" API.  You now can call begin()/
+      commit()/rollback() on the Session itself.
+
+    - Session also supports SAVEPOINT transactions; call begin_nested().
+
+    - Session supports two-phase commit behavior when vertically or
+      horizontally partitioning (i.e., using more than one engine).  Use
+      twophase=True.
+
+    - Session flag "transactional=True" produces a session which always places
+      itself into a transaction when first used.  Upon commit(), rollback() or
+      close(), the transaction ends; but begins again on the next usage.
+
+    - Session supports "autoflush=True".  This issues a flush() before each
+      query.  Use in conjunction with transactional, and you can just
+      save()/update() and then query, the new objects will be there.  Use
+      commit() at the end (or flush() if non-transactional) to flush remaining
+      changes.
+
+    - New scoped_session() function replaces SessionContext and assignmapper.
+      Builds onto "sessionmaker()" concept to produce a class whos Session()
+      construction returns the thread-local session.  Or, call all Session
+      methods as class methods, i.e. Session.save(foo); Session.commit().
+      just like the old "objectstore" days.
+
+    - Added new "binds" argument to Session to support configuration of
+      multiple binds with sessionmaker() function.
+
+    - A rudimental SessionExtension class has been added, allowing
+      user-defined functionality to take place at flush(), commit(), and
+      rollback() boundaries.
+
+  - Query-based relation()s available with dynamic_loader().  This is a
+    *writable* collection (supporting append() and remove()) which is also a
+    live Query object when accessed for reads.  Ideal for dealing with very
+    large collections where only partial loading is desired.
+
+  - flush()-embedded inline INSERT/UPDATE expressions.  Assign any SQL
+    expression, like "sometable.c.column + 1", to an instance's attribute.
+    Upon flush(), the mapper detects the expression and embeds it directly in
+    the INSERT or UPDATE statement; the attribute gets deferred on the
+    instance so it loads the new value the next time you access it.
+
+  - A rudimental sharding (horizontal scaling) system is introduced.  This
+    system uses a modified Session which can distribute read and write
+    operations among multiple databases, based on user-defined functions
+    defining the "sharding strategy".  Instances and their dependents can be
+    distributed and queried among multiple databases based on attribute
+    values, round-robin approaches or any other user-defined
+    system. [ticket:618]
+
+  - Eager loading has been enhanced to allow even more joins in more places.
+    It now functions at any arbitrary depth along self-referential and
+    cyclical structures.  When loading cyclical structures, specify
+    "join_depth" on relation() indicating how many times you'd like the table
+    to join to itself; each level gets a distinct table alias.  The alias
+    names themselves are generated at compile time using a simple counting
+    scheme now and are a lot easier on the eyes, as well as of course
+    completely deterministic. [ticket:659]
+
+  - Added composite column properties.  This allows you to create a type which
+    is represented by more than one column, when using the ORM.  Objects of
+    the new type are fully functional in query expressions, comparisons,
+    query.get() clauses, etc. and act as though they are regular single-column
+    scalars... except they're not!  Use the function composite(cls, *columns)
+    inside of the mapper's "properties" dict, and instances of cls will be
+    created/mapped to a single attribute, comprised of the values correponding
+    to *columns. [ticket:211]
+
+  - Improved support for custom column_property() attributes which feature
+    correlated subqueries, works better with eager loading now.
+
+  - Primary key "collapse" behavior; the mapper will analyze all columns in
+    its given selectable for primary key "equivalence", that is, columns which
+    are equivalent via foreign key relationship or via an explicit
+    inherit_condition. primarily for joined-table inheritance scenarios where
+    different named PK columns in inheriting tables should "collapse" into a
+    single-valued (or fewer-valued) primary key.  Fixes things like
+    [ticket:611].
+
+  - Joined-table inheritance will now generate the primary key columns of all
+    inherited classes against the root table of the join only.  This implies
+    that each row in the root table is distinct to a single instance.  If for
+    some rare reason this is not desireable, explicit primary_key settings on
+    individual mappers will override it.
+
+  - When "polymorphic" flags are used with joined-table or single-table
+    inheritance, all identity keys are generated against the root class of the
+    inheritance hierarchy; this allows query.get() to work polymorphically
+    using the same caching semantics as a non-polymorphic get.  Note that this
+    currently does not work with concrete inheritance.
+
+  - Secondary inheritance loading: polymorphic mappers can be constructed
+    *without* a select_table argument. inheriting mappers whose tables were
+    not represented in the initial load will issue a second SQL query
+    immediately, once per instance (i.e. not very efficient for large lists),
+    in order to load the remaining columns.
+
+  - Secondary inheritance loading can also move its second query into a
+    column-level "deferred" load, via the "polymorphic_fetch" argument, which
+    can be set to 'select' or 'deferred'
+
+  - It's now possible to map only a subset of available selectable columns
+    onto mapper properties, using include_columns/exclude_columns.
+    [ticket:696].
+
+  - Added undefer_group() MapperOption, sets a set of "deferred" columns
+    joined by a "group" to load as "undeferred".
+
+  - Rewrite of the "deterministic alias name" logic to be part of the SQL
+    layer, produces much simpler alias and label names more in the style of
+    Hibernate
+
+- sql
+
+  - Speed!  Clause compilation as well as the mechanics of SQL constructs have
+    been streamlined and simplified to a signficant degree, for a 20-30%
+    improvement of the statement construction/compilation overhead of 0.3.
+
+  - All "type" keyword arguments, such as those to bindparam(), column(),
+    Column(), and func.<something>(), renamed to "type_".  Those objects still
+    name their "type" attribute as "type".
+
+  - case_sensitive=(True|False) setting removed from schema items, since
+    checking this state added a lot of method call overhead and there was no
+    decent reason to ever set it to False.  Table and column names which are
+    all lower case will be treated as case-insenstive (yes we adjust for
+    Oracle's UPPERCASE style too).
+
+  - Transactions:
+
+    - Added context manager (with statement) support for transactions.
+    - Added support for two phase commit, works with mysql and postgres so far.
+    - Added a subtransaction implementation that uses savepoints.
+    - Added support for savepoints.
+
+  - MetaData:
+
+    - Tables can be reflected from the database en-masse without declaring
+      them in advance.  MetaData(engine, reflect=True) will load all tables
+      present in the database, or use metadata.reflect() for finer control.
+    - DynamicMetaData has been renamed to ThreadLocalMetaData
+    - The ThreadLocalMetaData constructor now takes no arguments.
+    - BoundMetaData has been removed- regular MetaData is equivalent
+
+  - Numeric and Float types now have an "asdecimal" flag; defaults to True for
+    Numeric, False for Float.  When True, values are returned as
+    decimal.Decimal objects; when False, values are returned as float().  The
+    defaults of True/False are already the behavior for PG and MySQL's DBAPI
+    modules. [ticket:646]
+
+  - New SQL operator implementation which removes all hardcoded operators from
+    expression structures and moves them into compilation; allows greater
+    flexibility of operator compilation; for example, "+" compiles to "||"
+    when used in a string context, or "concat(a,b)" on MySQL; whereas in a
+    numeric context it compiles to "+".  Fixes [ticket:475].
+
+  - "Anonymous" alias and label names are now generated at SQL compilation
+    time in a completely deterministic fashion... no more random hex IDs
+
+  - Significant architectural overhaul to SQL elements (ClauseElement).  All
+    elements share a common "mutability" framework which allows a consistent
+    approach to in-place modifications of elements as well as generative
+    behavior.  Improves stability of the ORM which makes heavy usage of
+    mutations to SQL expressions.
+
+  - select() and union()'s now have "generative" behavior.  Methods like
+    order_by() and group_by() return a *new* instance - the original instance
+    is left unchanged.  Non-generative methods remain as well.
+
+  - The internals of select/union vastly simplified- all decision making
+    regarding "is subquery" and "correlation" pushed to SQL generation phase.
+    select() elements are now *never* mutated by their enclosing containers or
+    by any dialect's compilation process [ticket:52] [ticket:569]
+
+  - select(scalar=True) argument is deprecated; use select(..).as_scalar().
+    The resulting object obeys the full "column" interface and plays better
+    within expressions.
+
+  - Added select().with_prefix('foo') allowing any set of keywords to be
+    placed before the columns clause of the SELECT [ticket:504]
+
+  - Added array slice support to row[<index>] [ticket:686]
+
+  - Result sets make a better attempt at matching the DBAPI types present in
+    cursor.description to the TypeEngine objects defined by the dialect, which
+    are then used for result-processing. Note this only takes effect for
+    textual SQL; constructed SQL statements always have an explicit type map.
+
+  - Result sets from CRUD operations close their underlying cursor immediately
+    and will also autoclose the connection if defined for the operation; this
+    allows more efficient usage of connections for successive CRUD operations
+    with less chance of "dangling connections".
+
+  - Column defaults and onupdate Python functions (i.e. passed to
+    ColumnDefault) may take zero or one arguments; the one argument is the
+    ExecutionContext, from which you can call "context.parameters[someparam]"
+    to access the other bind parameter values affixed to the statement
+    [ticket:559].  The connection used for the execution is available as well
+    so that you can pre-execute statements.
+
+  - Added "explcit" create/drop/execute support for sequences (i.e. you can
+    pass a "connectable" to each of those methods on Sequence).
+
+  - Better quoting of identifiers when manipulating schemas.
+
+  - Standardized the behavior for table reflection where types can't be
+    located; NullType is substituted instead, warning is raised.
+
+  - ColumnCollection (i.e. the 'c' attribute on tables) follows dictionary
+    semantics for "__contains__" [ticket:606]
+
+- engines
+
+  - Speed! The mechanics of result processing and bind parameter processing
+    have been overhauled, streamlined and optimized to issue as little method
+    calls as possible.  Bench tests for mass INSERT and mass rowset iteration
+    both show 0.4 to be over twice as fast as 0.3, using 68% fewer function
+    calls.
+
+  - You can now hook into the pool lifecycle and run SQL statements or other
+    logic at new each DBAPI connection, pool check-out and check-in.
+
+  - Connections gain a .properties collection, with contents scoped to the
+    lifetime of the underlying DBAPI connection
+
+  - Removed auto_close_cursors and disallow_open_cursors arguments from Pool;
+    reduces overhead as cursors are normally closed by ResultProxy and
+    Connection.
+
+- extensions
+
+  - proxyengine is temporarily removed, pending an actually working
+    replacement.
+
+  - SelectResults has been replaced by Query.  SelectResults /
+    SelectResultsExt still exist but just return a slightly modified Query
+    object for backwards-compatibility.  join_to() method from SelectResults
+    isn't present anymore, need to use join().
+
+- mysql
+
+  - Table and column names loaded via reflection are now Unicode.
+
+  - All standard column types are now supported, including SET.
+
+  - Table reflection can now be performed in as little as one round-trip.
+
+  - ANSI and ANSI_QUOTES sql modes are now supported.
+
+  - Indexes are now reflected.
+
+- postgres
+
+  - Added PGArray datatype for using postgres array datatypes.
+
+- oracle
+
+  - Very rudimental support for OUT parameters added; use sql.outparam(name,
+    type) to set up an OUT parameter, just like bindparam(); after execution,
+    values are avaiable via result.out_parameters dictionary. [ticket:507]
+
+0.3.11
+------
+
+- sql
+
+    - tweak DISTINCT precedence for clauses like
+      `func.count(t.c.col.distinct())`
+
+    - Fixed detection of internal '$' characters in :bind$params [ticket:719]
+
+    - [ticket:768] dont assume join criterion consists only of column objects
+
+    - adjusted operator precedence of NOT to match '==' and others, so that
+      ~(x==y) produces NOT (x=y), which is compatible with MySQL < 5.0
+      (doesn't like "NOT x=y") [ticket:764]
+
+- orm
+
+    - added a check for joining from A->B using join(), along two
+      different m2m tables.  this raises an error in 0.3 but is
+      possible in 0.4 when aliases are used. [ticket:687]
+
+    - fixed small exception throw bug in Session.merge()
+
+    - fixed bug where mapper, being linked to a join where one table had
+      no PK columns, would not detect that the joined table had no PK.
+
+    - fixed bugs in determining proper sync clauses from custom inherit
+      conditions [ticket:769]
+
+    - backref remove object operation doesn't fail if the other-side
+      collection doesn't contain the item, supports noload collections
+      [ticket:813]
+
+- engine
+
+    - fixed another occasional race condition which could occur
+      when using pool with threadlocal setting
+
+- mysql
+    - fixed specification of YEAR columns when generating schema
+
+- mssql
+
+    - added support for TIME columns (simulated using DATETIME) [ticket:679]
+
+    - added support for BIGINT, MONEY, SMALLMONEY, UNIQUEIDENTIFIER and
+      SQL_VARIANT [ticket:721]
+
+    - index names are now quoted when dropping from reflected tables
+      [ticket:684]
+
+    - can now specify a DSN for PyODBC, using a URI like mssql:///?dsn=bob
+
+- postgres
+
+    - when reflecting tables from alternate schemas, the "default" placed upon
+      the primary key, i.e. usually a sequence name, has the "schema" name
+      unconditionally quoted, so that schema names which need quoting are fine.
+      its slightly unnecessary for schema names which don't need quoting
+      but not harmful.
+
+- sqlite
+   - passthrough for stringified dates
+
+- firebird
+    - supports_sane_rowcount() set to False due to ticket #370 (right way).
+    - fixed reflection of Column's nullable property.
+
+- oracle
+    - removed LONG_STRING, LONG_BINARY from "binary" types, so type objects
+      don't try to read their values as LOB [ticket:622], [ticket:751]
+
+0.3.10
+- general
+    - a new mutex that was added in 0.3.9 causes the pool_timeout
+      feature to fail during a race condition; threads would
+      raise TimeoutError immediately with no delay if many threads
+      push the pool into overflow at the same time.  this issue has been
+      fixed.
+- sql
+  - got connection-bound metadata to work with implicit execution
+  - foreign key specs can have any chararcter in their identifiers
+   [ticket:667]
+  - added commutativity-awareness to binary clause comparisons to
+    each other, improves ORM lazy load optimization [ticket:664]
+- orm
+  - cleanup to connection-bound sessions, SessionTransaction
+- postgres
+  - fixed max identifier length (63) [ticket:571]
+
+
+0.3.9
+- general
+    - better error message for NoSuchColumnError [ticket:607]
+    - finally figured out how to get setuptools version in, available
+      as sqlalchemy.__version__ [ticket:428]
+    - the various "engine" arguments, such as "engine", "connectable",
+      "engine_or_url", "bind_to", etc. are all present, but deprecated.
+      they all get replaced by the single term "bind".  you also
+      set the "bind" of MetaData using
+      metadata.bind = <engine or connection>
+- ext
+    - iteration over dict association proxies is now dict-like, not
+      InstrumentedList-like (e.g. over keys instead of values)
+    - association proxies no longer bind tightly to source collections
+      [ticket:597], and are constructed with a thunk instead
+    - added selectone_by() to assignmapper
+- orm
+    - forwards-compatibility with 0.4: added one(), first(), and
+      all() to Query.  almost all Query functionality from 0.4 is
+      present in 0.3.9 for forwards-compat purposes.
+    - reset_joinpoint() really really works this time, promise ! lets
+      you re-join from the root:
+      query.join(['a', 'b']).filter(<crit>).reset_joinpoint().\
+      join(['a', 'c']).filter(<some other crit>).all()
+      in 0.4 all join() calls start from the "root"
+    - added synchronization to the mapper() construction step, to avoid
+      thread collisions when pre-existing mappers are compiling in a
+      different thread [ticket:613]
+    - a warning is issued by Mapper when two primary key columns of the
+      same name are munged into a single attribute.  this happens frequently
+      when mapping to joins (or inheritance).
+    - synonym() properties are fully supported by all Query joining/
+      with_parent operations [ticket:598]
+    - fixed very stupid bug when deleting items with many-to-many
+      uselist=False relations
+    - remember all that stuff about polymorphic_union ?  for
+      joined table inheritance ?  Funny thing...
+      You sort of don't need it for joined table inheritance, you
+      can just string all the tables together via outerjoin().
+      The UNION still applies if concrete tables are involved,
+      though (since nothing to join them on).
+    - small fix to eager loading to better work with eager loads
+      to polymorphic mappers that are using a straight "outerjoin"
+      clause
+- sql
+    - ForeignKey to a table in a schema thats not the default schema
+      requires the schema to be explicit; i.e. ForeignKey('alt_schema.users.id')
+    - MetaData can now be constructed with an engine or url as the first
+      argument, just like BoundMetaData
+    - BoundMetaData is now deprecated, and MetaData is a direct substitute.
+    - DynamicMetaData has been renamed to ThreadLocalMetaData.  the
+      DynamicMetaData name is deprecated and is an alias for ThreadLocalMetaData
+      or a regular MetaData if threadlocal=False
+    - composite primary key is represented as a non-keyed set to allow for
+      composite keys consisting of cols with the same name; occurs within a
+      Join.  helps inheritance scenarios formulate correct PK.
+    - improved ability to get the "correct" and most minimal set of primary key
+      columns from a join, equating foreign keys and otherwise equated columns.
+      this is also mostly to help inheritance scenarios formulate the best
+      choice of primary key columns.  [ticket:185]
+    - added 'bind' argument to Sequence.create()/drop(), ColumnDefault.execute()
+    - columns can be overridden in a reflected table with a "key"
+      attribute different than the column's name, including for primary key
+      columns [ticket:650]
+    - fixed "ambiguous column" result detection, when dupe col names exist
+      in a result [ticket:657]
+    - some enhancements to "column targeting", the ability to match a column
+      to a "corresponding" column in another selectable.  this affects mostly
+      ORM ability to map to complex joins
+    - MetaData and all SchemaItems are safe to use with pickle.  slow
+      table reflections can be dumped into a pickled file to be reused later.
+      Just reconnect the engine to the metadata after unpickling. [ticket:619]
+    - added a mutex to QueuePool's "overflow" calculation to prevent a race
+      condition that can bypass max_overflow
+    - fixed grouping of compound selects to give correct results. will break
+      on sqlite in some cases, but those cases were producing incorrect
+      results anyway, sqlite doesn't support grouped compound selects
+      [ticket:623]
+    - fixed precedence of operators so that parenthesis are correctly applied
+      [ticket:620]
+    - calling <column>.in_() (i.e. with no arguments) will return
+      "CASE WHEN (<column> IS NULL) THEN NULL ELSE 0 END = 1)", so that
+      NULL or False is returned in all cases, rather than throwing an error
+      [ticket:545]
+    - fixed "where"/"from" criterion of select() to accept a unicode string
+      in addition to regular string - both convert to text()
+    - added standalone distinct() function in addition to column.distinct()
+      [ticket:558]
+    - result.last_inserted_ids() should return a list that is identically
+      sized to the primary key constraint of the table.  values that were
+      "passively" created and not available via cursor.lastrowid will be None.
+    - long-identifier detection fixed to use > rather than >= for
+      max ident length [ticket:589]
+    - fixed bug where selectable.corresponding_column(selectable.c.col)
+      would not return selectable.c.col, if the selectable is a join
+      of a table and another join involving the same table.  messed
+      up ORM decision making [ticket:593]
+    - added Interval type to types.py [ticket:595]
+- mysql
+    - fixed catching of some errors that imply a dropped connection [ticket:625]
+    - fixed escaping of the modulo operator [ticket:624]
+    - added 'fields' to reserved words [ticket:590]
+    - various reflection enhancement/fixes
+- oracle
+    - datetime fixes: got subsecond TIMESTAMP to work [ticket:604],
+      added OracleDate which supports types.Date with only year/month/day
+    - added dialect flag "auto_convert_lobs", defaults to True; will cause any
+      LOB objects detected in a result set to be forced into OracleBinary
+      so that the LOB is read() automatically, if no typemap was present
+      (i.e., if a textual execute() was issued).
+    - mod operator '%' produces MOD [ticket:624]
+    - converts cx_oracle datetime objects to Python datetime.datetime when
+      Python 2.3 used [ticket:542]
+    - fixed unicode conversion in Oracle TEXT type
+- postgres
+    - fixed escaping of the modulo operator [ticket:624]
+    - added support for reflection of domains [ticket:570]
+    - types which are missing during reflection resolve to Null type
+      instead of raising an error
+    - the fix in "schema" above fixes reflection of foreign keys from an
+      alt-schema table to a public schema table
+- sqlite
+    - rearranged dialect initialization so it has time to warn about pysqlite1
+      being too old.
+    - sqlite better handles datetime/date/time objects mixed and matched
+      with various Date/Time/DateTime columns
+    - string PK column inserts dont get overwritten with OID [ticket:603]
+- mssql
+    - fix port option handling for pyodbc [ticket:634]
+    - now able to reflect start and increment values for identity columns
+    - preliminary support for using scope_identity() with pyodbc
+
+0.3.8
+- engines
+  - added detach() to Connection, allows underlying DBAPI connection
+    to be detached from its pool, closing on dereference/close()
+    instead of being reused by the pool.
+  - added invalidate() to Connection, immediately invalidates the
+    Connection and its underlying DBAPI connection.
+- sql
+  - _Label class overrides compare_self to return its ultimate
+    object. meaning, if you say someexpr.label('foo') == 5, it
+    produces the correct "someexpr == 5".
+  - _Label propagates "_hide_froms()" so that scalar selects
+    behave more properly with regards to FROM clause #574
+  - fix to long name generation when using oid_column as an order by
+    (oids used heavily in mapper queries)
+  - significant speed improvement to ResultProxy, pre-caches
+    TypeEngine dialect implementations and saves on function calls
+    per column
+  - parenthesis are applied to clauses via a new _Grouping
+    construct. uses operator precedence to more intelligently apply
+    parenthesis to clauses, provides cleaner nesting of clauses
+    (doesnt mutate clauses placed in other clauses, i.e. no 'parens'
+    flag)
+  - added 'modifier' keyword, works like func.<foo> except does not
+    add parenthesis.  e.g. select([modifier.DISTINCT(...)]) etc.
+  - removed "no group by's in a select thats part of a UNION"
+    restriction [ticket:578]
+- orm
+  - added reset_joinpoint() method to Query, moves the "join point"
+    back to the starting mapper. 0.4 will change the behavior of
+    join() to reset the "join point" in all cases so this is an
+    interim method. for forwards compatibility, ensure joins across
+    multiple relations are specified using a single join(), i.e.
+    join(['a', 'b', 'c']).
+  - fixed bug in query.instances() that wouldnt handle more than
+    on additional mapper or one additional column.
+  - "delete-orphan" no longer implies "delete". ongoing effort to
+    separate the behavior of these two operations.
+  - many-to-many relationships properly set the type of bind params
+    for delete operations on the association table
+  - many-to-many relationships check that the number of rows deleted
+    from the association table by a delete operation matches the
+    expected results
+  - session.get() and session.load() propagate **kwargs through to
+    query
+  - fix to polymorphic query which allows the original
+    polymorphic_union to be embedded into a correlated subquery
+    [ticket:577]
+  - fix to select_by(<propname>=<object instance>) -style joins in
+    conjunction with many-to-many relationships, bug introduced in
+    r2556
+  - the "primary_key" argument to mapper() is propagated to the
+    "polymorphic" mapper. primary key columns in this list get
+    normalized to that of the mapper's local table.
+  - restored logging of "lazy loading clause" under
+    sa.orm.strategies logger, got removed in 0.3.7
+  - improved support for eagerloading of properties off of mappers
+    that are mapped to select() statements; i.e. eagerloader is
+    better at locating the correct selectable with which to attach
+    its LEFT OUTER JOIN.
+- mysql
+  - Nearly all MySQL column types are now supported for declaration
+    and reflection. Added NCHAR, NVARCHAR, VARBINARY, TINYBLOB,
+    LONGBLOB, YEAR
+  - The sqltypes.Binary passthrough now always builds a BLOB,
+    avoiding problems with very old database versions
+  - support for column-level CHARACTER SET and COLLATE declarations,
+    as well as ASCII, UNICODE, NATIONAL and BINARY shorthand.
+- firebird
+  - set max identifier length to 31
+  - supports_sane_rowcount() set to False due to ticket #370.
+    versioned_id_col feature wont work in FB.
+  - some execution fixes
+-extensions
+  - new association proxy implementation, implementing complete
+    proxies to list, dict and set-based relation collections
+  - added orderinglist, a custom list class that synchronizes an
+    object attribute with that object's position in the list
+  - small fix to SelectResultsExt to not bypass itself during
+    select().
+  - added filter(), filter_by() to assignmapper
+
+0.3.7
+- engines
+    - warnings module used for issuing warnings (instead of logging)
+    - cleanup of DBAPI import strategies across all engines
+      [ticket:480]
+    - refactoring of engine internals which reduces complexity,
+      number of codepaths; places more state inside of ExecutionContext
+      to allow more dialect control of cursor handling, result sets.
+      ResultProxy totally refactored and also has two versions of
+      "buffered" result sets used for different purposes.
+    - server side cursor support fully functional in postgres
+      [ticket:514].
+    - improved framework for auto-invalidation of connections that have
+      lost their underlying database, via dialect-specific detection
+      of exceptions corresponding to that database's disconnect
+      related error messages.  Additionally, when a "connection no
+      longer open" condition is detected, the entire connection pool
+      is discarded and replaced with a new instance.  #516
+    - the dialects within sqlalchemy.databases become a setuptools
+      entry points. loading the built-in database dialects works the
+      same as always, but if none found will fall back to trying
+      pkg_resources to load an external module [ticket:521]
+    - Engine contains a "url" attribute referencing the url.URL object
+      used by create_engine().
+- sql:
+    - keys() of result set columns are not lowercased, come back
+      exactly as they're expressed in cursor.description.  note this
+      causes colnames to be all caps in oracle.
+    - preliminary support for unicode table names, column names and
+      SQL statements added, for databases which can support them.
+      Works with sqlite and postgres so far.  Mysql *mostly* works
+      except the has_table() function does not work.  Reflection
+      works too.
+    - the Unicode type is now a direct subclass of String, which now
+      contains all the "convert_unicode" logic.  This helps the variety
+      of unicode situations that occur in db's such as MS-SQL to be
+      better handled and allows subclassing of the Unicode datatype.
+      [ticket:522]
+    - ClauseElements can be used in in_() clauses now, such as bind
+      parameters, etc. #476
+    - reverse operators implemented for `CompareMixin` elements,
+      allows expressions like "5 + somecolumn" etc. #474
+    - the "where" criterion of an update() and delete() now correlates
+      embedded select() statements against the table being updated or
+      deleted.  this works the same as nested select() statement
+      correlation, and can be disabled via the correlate=False flag on
+      the embedded select().
+    - column labels are now generated in the compilation phase, which
+      means their lengths are dialect-dependent.  So on oracle a label
+      that gets truncated to 30 chars will go out to 63 characters
+      on postgres.  Also, the true labelname is always attached as the
+      accessor on the parent Selectable so theres no need to be aware
+      of the "truncated" label names [ticket:512].
+    - column label and bind param "truncation" also generate
+      deterministic names now, based on their ordering within the
+      full statement being compiled.  this means the same statement
+      will produce the same string across application restarts and
+      allowing DB query plan caching to work better.
+    - the "mini" column labels generated when using subqueries, which
+      are to work around glitchy SQLite behavior that doesnt understand
+      "foo.id" as equivalent to "id", are now only generated in the case
+      that those named columns are selected from (part of [ticket:513])
+    - the label() method on ColumnElement will properly propagate the
+      TypeEngine of the base element out to the label, including a label()
+      created from a scalar=True select() statement.
+    - MS-SQL better detects when a query is a subquery and knows not to
+      generate ORDER BY phrases for those [ticket:513]
+    - fix for fetchmany() "size" argument being positional in most
+      dbapis [ticket:505]
+    - sending None as an argument to func.<something> will produce
+      an argument of NULL
+    - query strings in unicode URLs get keys encoded to ascii
+      for **kwargs compat
+    - slight tweak to raw execute() change to also support tuples
+      for positional parameters, not just lists [ticket:523]
+    - fix to case() construct to propagate the type of the first
+      WHEN condition as the return type of the case statement
+- orm:
+    - fixed critical issue when, after options(eagerload()) is used,
+      the mapper would then always apply query "wrapping" behavior
+      for all subsequent LIMIT/OFFSET/DISTINCT queries, even if no
+      eager loading was applied on those subsequent queries.
+    - added query.with_parent(someinstance) method.  searches for
+      target instance using lazy join criterion from parent instance.
+      takes optional string "property" to isolate the desired relation.
+      also adds static Query.query_from_parent(instance, property)
+      version. [ticket:541]
+    - improved query.XXX_by(someprop=someinstance) querying to use
+      similar methodology to with_parent, i.e. using the "lazy" clause
+      which prevents adding the remote instance's table to the SQL,
+      thereby making more complex conditions possible [ticket:554]
+    - added generative versions of aggregates, i.e. sum(), avg(), etc.
+      to query. used via query.apply_max(), apply_sum(), etc.
+      #552
+    - fix to using distinct() or distinct=True in combination with
+      join() and similar
+    - corresponding to label/bindparam name generation, eager loaders
+      generate deterministic names for the aliases they create using
+      md5 hashes.
+    - improved/fixed custom collection classes when giving it "set"/
+      "sets.Set" classes or subclasses (was still looking for append()
+      methods on them during lazy loads)
+    - restored old "column_property()" ORM function (used to be called
+      "column()") to force any column expression to be added as a property
+      on a mapper, particularly those that aren't present in the mapped
+      selectable.  this allows "scalar expressions" of any kind to be
+      added as relations (though they have issues with eager loads).
+    - fix to many-to-many relationships targeting polymorphic mappers
+      [ticket:533]
+    - making progress with session.merge() as well as combining its
+      usage with entity_name [ticket:543]
+    - the usual adjustments to relationships between inheriting mappers,
+      in this case establishing relation()s to subclass mappers where
+      the join conditions come from the superclass' table
+- informix:
+    - informix support added !  courtesy James Zhang, who put a ton
+      of effort in.
+- sqlite:
+    - removed silly behavior where sqlite would reflect UNIQUE indexes
+      as part of the primary key (?!)
+- oracle:
+    - small fix to allow successive compiles of the same SELECT object
+      which features LIMIT/OFFSET.  oracle dialect needs to modify
+      the object to have ROW_NUMBER OVER and wasn't performing
+      the full series of steps on successive compiles.
+- mysql
+    - support for SSL arguments given as inline within URL query string,
+      prefixed with "ssl_", courtesy terjeros@gmail.com.
+    - mysql uses "DESCRIBE [<schemaname>].<tablename>", catching exceptions
+      if table doesnt exist, in order to determine if a table exists.
+      this supports unicode table names as well as schema names. tested
+      with MySQL5 but should work with 4.1 series as well. (#557)
+- extensions
+    - big fix to AssociationProxy so that multiple AssociationProxy
+      objects can be associated with a single association collection.
+    - assign_mapper names methods according to their keys (i.e. __name__)
+      #551
+- mssql
+    - pyodbc is now the preferred DB-API for MSSQL, and if no module is
+      specifically requested, will be loaded first on a module probe.
+
+    - The @@SCOPE_IDENTITY is now used instead of @@IDENTITY. This
+      behavior may be overridden with the engine_connect
+      "use_scope_identity" keyword parameter, which may also be specified
+      in the dburi.
+
+
+
+0.3.6
+- sql:
+    - bindparam() names are now repeatable!  specify two
+      distinct bindparam()s with the same name in a single statement,
+      and the key will be shared.  proper positional/named args translate
+      at compile time.  for the old behavior of "aliasing" bind parameters
+      with conflicting names, specify "unique=True" - this option is
+      still used internally for all the auto-genererated (value-based)
+      bind parameters.
+
+    - slightly better support for bind params as column clauses, either
+      via bindparam() or via literal(), i.e. select([literal('foo')])
+
+    - MetaData can bind to an engine either via "url" or "engine" kwargs
+      to constructor, or by using connect() method. BoundMetaData is
+      identical to MetaData except engine_or_url param is required.
+      DynamicMetaData is the same and provides thread-local connections be
+      default.
+
+    - exists() becomes useable as a standalone selectable, not just in a
+      WHERE clause, i.e. exists([columns], criterion).select()
+
+    - correlated subqueries work inside of ORDER BY, GROUP BY
+
+    - fixed function execution with explicit connections, i.e.
+      conn.execute(func.dosomething())
+
+    - use_labels flag on select() wont auto-create labels for literal text
+      column elements, since we can make no assumptions about the text. to
+      create labels for literal columns, you can say "somecol AS
+      somelabel", or use literal_column("somecol").label("somelabel")
+
+    - quoting wont occur for literal columns when they are "proxied" into
+      the column collection for their selectable (is_literal flag is
+      propagated). literal columns are specified via
+      literal_column("somestring").
+
+    - added "fold_equivalents" boolean argument to Join.select(), which
+      removes 'duplicate' columns from the resulting column clause that
+      are known to be equivalent based on the join condition. this is of
+      great usage when constructing subqueries of joins which Postgres
+      complains about if duplicate column names are present.
+
+    - fixed use_alter flag on ForeignKeyConstraint [ticket:503]
+
+    - fixed usage of 2.4-only "reversed" in topological.py [ticket:506]
+
+    - for hackers, refactored the "visitor" system of ClauseElement and
+      SchemaItem so that the traversal of items is controlled by the
+      ClauseVisitor itself, using the method visitor.traverse(item).
+      accept_visitor() methods can still be called directly but will not
+      do any traversal of child items. ClauseElement/SchemaItem now have a
+      configurable get_children() method to return the collection of child
+      elements for each parent object. This allows the full traversal of
+      items to be clear and unambiguous (as well as loggable), with an
+      easy method of limiting a traversal (just pass flags which are
+      picked up by appropriate get_children() methods). [ticket:501]
+
+    - the "else_" parameter to the case statement now properly works when
+      set to zero.
+
+- orm:
+    - the full featureset of the SelectResults extension has been merged
+      into a new set of methods available off of Query.  These methods
+      all provide "generative" behavior, whereby the Query is copied
+      and a new one returned with additional criterion added.
+      The new methods include:
+
+          filter() - applies select criterion to the query
+          filter_by() - applies "by"-style criterion to the query
+          avg() - return the avg() function on the given column
+          join() - join to a property (or across a list of properties)
+          outerjoin() - like join() but uses LEFT OUTER JOIN
+          limit()/offset() - apply LIMIT/OFFSET
+          range-based access which applies limit/offset:
+             session.query(Foo)[3:5]
+          distinct() - apply DISTINCT
+          list() - evaluate the criterion and return results
+
+      no incompatible changes have been made to Query's API and no methods
+      have been deprecated.  Existing methods like select(), select_by(),
+      get(), get_by() all execute the query at once and return results
+      like they always did.  join_to()/join_via() are still there although
+      the generative join()/outerjoin() methods are easier to use.
+
+    - the return value for multiple mappers used with instances() now
+      returns a cartesian product of the requested list of mappers,
+      represented as a list of tuples. this corresponds to the documented
+      behavior. So that instances match up properly, the "uniquing" is
+      disabled when this feature is used.
+
+    - Query has add_entity() and add_column() generative methods. these
+      will add the given mapper/class or ColumnElement to the query at
+      compile time, and apply them to the instances() method. the user is
+      responsible for constructing reasonable join conditions (otherwise
+      you can get full cartesian products). result set is the list of
+      tuples, non-uniqued.
+
+    - strings and columns can also be sent to the *args of instances()
+      where those exact result columns will be part of the result tuples.
+
+    - a full select() construct can be passed to query.select() (which
+      worked anyway), but also query.selectfirst(), query.selectone()
+      which will be used as is (i.e. no query is compiled). works
+      similarly to sending the results to instances().
+
+    - eager loading will not "aliasize" "order by" clauses that were
+      placed in the select statement by something other than the eager
+      loader itself, to fix possibility of dupe columns as illustrated in
+      [ticket:495]. however, this means you have to be more careful with
+      the columns placed in the "order by" of Query.select(), that you
+      have explicitly named them in your criterion (i.e. you cant rely on
+      the eager loader adding them in for you)
+
+    - added a handy multi-use "identity_key()" method to Session, allowing
+      the generation of identity keys for primary key values, instances,
+      and rows, courtesy Daniel Miller
+
+    - many-to-many table will be properly handled even for operations that
+      occur on the "backref" side of the operation [ticket:249]
+
+    - added "refresh-expire" cascade [ticket:492].  allows refresh() and
+      expire() calls to propagate along relationships.
+
+    - more fixes to polymorphic relations, involving proper lazy-clause
+      generation on many-to-one relationships to polymorphic mappers
+      [ticket:493]. also fixes to detection of "direction", more specific
+      targeting of columns that belong to the polymorphic union vs. those
+      that dont.
+
+    - some fixes to relationship calcs when using "viewonly=True" to pull
+      in other tables into the join condition which arent parent of the
+      relationship's parent/child mappings
+
+    - flush fixes on cyclical-referential relationships that contain
+      references to other instances outside of the cyclical chain, when
+      some of the objects in the cycle are not actually part of the flush
+
+    - put an aggressive check for "flushing object A with a collection of
+      B's, but you put a C in the collection" error condition - **even if
+      C is a subclass of B**, unless B's mapper loads polymorphically.
+      Otherwise, the collection will later load a "B" which should be a
+      "C" (since its not polymorphic) which breaks in bi-directional
+      relationships (i.e. C has its A, but A's backref will lazyload it as
+      a different instance of type "B") [ticket:500] This check is going
+      to bite some of you who do this without issues, so the error message
+      will also document a flag "enable_typechecks=False" to disable this
+      checking. But be aware that bi-directional relationships in
+      particular become fragile without this check.
+
+- extensions:
+    - options() method on SelectResults now implemented "generatively"
+      like the rest of the SelectResults methods [ticket:472].  But
+      you're going to just use Query now anyway.
+
+    - query() method is added by assignmapper.  this helps with
+      navigating to all the new generative methods on Query.
+
+- ms-sql:
+    - removed seconds input on DATE column types (probably
+        should remove the time altogether)
+
+    - null values in float fields no longer raise errors
+
+    - LIMIT with OFFSET now raises an error (MS-SQL has no OFFSET support)
+
+    - added an facility to use the MSSQL type VARCHAR(max) instead of TEXT
+      for large unsized string fields. Use the new "text_as_varchar" to
+      turn it on. [ticket:509]
+
+    - ORDER BY clauses without a LIMIT are now stripped in subqueries, as
+      MS-SQL forbids this usage
+
+    - cleanup of module importing code; specifiable DB-API module; more
+      explicit ordering of module preferences. [ticket:480]
+
+- oracle:
+    - got binary working for any size input !  cx_oracle works fine,
+      it was my fault as BINARY was being passed and not BLOB for
+      setinputsizes (also unit tests werent even setting input sizes).
+
+    - also fixed CLOB read/write on a separate changeset.
+
+    - auto_setinputsizes defaults to True for Oracle, fixed cases where
+      it improperly propagated bad types.
+
+- mysql:
+    - added a catchall **kwargs to MSString, to help reflection of
+      obscure types (like "varchar() binary" in MS 4.0)
+
+    - added explicit MSTimeStamp type which takes effect when using
+      types.TIMESTAMP.
+
+
+0.3.5
+- sql:
+    - the value of "case_sensitive" defaults to True now, regardless of the
+      casing of the identifier, unless specifically set to False. this is
+      because the object might be label'ed as something else which does
+      contain mixed case, and propigating "case_sensitive=False" breaks that.
+      Other fixes to quoting when using labels and "fake" column objects
+    - added a "supports_execution()" method to ClauseElement, so that
+      individual kinds of clauses can express if they are appropriate for
+      executing...such as, you can execute a "select", but not a "Table" or a
+      "Join".
+    - fixed argument passing to straight textual execute() on engine,
+      connection. can handle *args or a list instance for positional, **kwargs
+      or a dict instance for named args, or a list of list or dicts to invoke
+      executemany()
+    - small fix to BoundMetaData to accept unicode or string URLs
+    - fixed named PrimaryKeyConstraint generation [ticket:466] courtesy
+      andrija at gmail
+    - fixed generation of CHECK constraints on columns [ticket:464]
+    - fixes to tometadata() operation to propagate Constraints at column and
+      table level
+- oracle:
+    - when returning "rowid" as the ORDER BY column or in use with ROW_NUMBER
+      OVER, oracle dialect checks the selectable its being applied to and will
+      switch to table PK if not applicable, i.e. for a UNION. checking for
+      DISTINCT, GROUP BY (other places that rowid is invalid) still a TODO.
+      allows polymorphic mappings to function, [ticket:436]
+    - sequences on a non-pk column will properly fire off on INSERT
+    - added PrefetchingResultProxy support to pre-fetch LOB columns when they
+      are known to be present, fixes [ticket:435]
+    - implemented reflection of tables based on synonyms, including across
+      dblinks [ticket:379]
+    - issues a log warning when a related table cant be reflected due to
+      certain permission errors [ticket:363]
+- mysql:
+    - fix to reflection on older DB's that might return array() type for
+    "show variables like" statements
+- postgres:
+    - better reflection of sequences for alternate-schema Tables [ticket:442]
+    - sequences on a non-pk column will properly fire off on INSERT
+    - added PGInterval type [ticket:460], PGInet type [ticket:444]
+- mssql:
+    - preliminary support for pyodbc (Yay!) [ticket:419]
+    - better support for NVARCHAR types added [ticket:298]
+    - fix for commit logic on pymssql
+    - fix for query.get() with schema [ticket:456]
+    - fix for non-integer relationships [ticket:473]
+    - DB-API module now selectable at run-time [ticket:419]
+    - now passes many more unit tests [tickets:422, 481, 415]
+    - better unittest compatibility with ANSI functions [ticket:479]
+    - improved support for implicit sequence PK columns with auto-insert
+      [ticket:415]
+    - fix for blank password in adodbapi [ticket:371]
+    - fixes to get unit tests working with pyodbc [ticket:481]
+    - fix to auto_identity_insert on db-url query
+    - added query_timeout to db-url query parms. currently works only for
+      pymssql
+    - tested with pymssql 0.8.0 (which is now LGPL)
+- orm bugs:
+    - another refactoring to relationship calculation. Allows more accurate
+      ORM behavior with relationships from/to/between mappers, particularly
+      polymorphic mappers, also their usage with Query, SelectResults. tickets
+      include [ticket:439], [ticket:441], [ticket:448].
+    - removed deprecated method of specifying custom collections on classes;
+      you must now use the "collection_class" option. the old way was
+      beginning to produce conflicts when people used assign_mapper(), which
+      now patches an "options" method, in conjunction with a relationship
+      named "options". (relationships take precedence over monkeypatched
+      assign_mapper methods).
+    - extension() query option propagates to Mapper._instance() method so that
+      all loading-related methods get called [ticket:454]
+    - eager relation to an inheriting mapper wont fail if no rows returned for
+      the relationship.
+    - eager relation loading bug fixed for eager relation on multiple
+      descendant classes [ticket:486]
+    - fix for very large topological sorts, courtesy ants.aasma at gmail
+      [ticket:423]
+    - eager loading is slightly more strict about detecting "self-referential"
+      relationships, specifically between polymorphic mappers. this results in
+      an "eager degrade" to lazy loading.
+    - improved support for complex queries embedded into "where" criterion for
+      query.select() [ticket:449]
+    - mapper options like eagerload(), lazyload(), deferred(), will work for
+      "synonym()" relationships [ticket:485]
+    - fixed bug where cascade operations incorrectly included deleted
+      collection items in the cascade [ticket:445]
+    - fixed relationship deletion error when one-to-many child item is moved
+      to a new parent in a single unit of work [ticket:478]
+    - fixed relationship deletion error where parent/child with a single
+      column as PK/FK on the child would raise a "blank out the primary key"
+      error, if manually deleted or "delete" cascade without "delete-orphan"
+      was used
+    - fix to deferred so that load operation doesnt mistakenly occur when only
+      PK col attributes are set
+- orm enhancements:
+    - implemented foreign_keys argument to mapper [ticket:385]. use in
+      conjunction with primaryjoin/secondaryjoin arguments to specify/override
+      foreign keys defined on the Table instance.
+    - contains_eager('foo') automatically implies eagerload('foo')
+    - added "alias" argument to contains_eager(). use it to specify the string
+      name or Alias instance of an alias used in the query for the eagerly
+      loaded child items. easier to use than "decorator"
+    - added "contains_alias()" option for result set mapping to an alias of
+      the mapped table
+    - added support for py2.5 "with" statement with SessionTransaction
+      [ticket:468]
+- extensions:
+    - added distinct() method to SelectResults. generally should only make a
+      difference when using count().
+    - added options() method to SelectResults, equivalent to query.options()
+      [ticket:472]
+    - added optional __table_opts__ dictionary to ActiveMapper, will send kw
+      options to Table objects [ticket:462]
+    - added selectfirst(), selectfirst_by() to assign_mapper [ticket:467]
+
+0.3.4
+- general:
+  - global "insure"->"ensure" change. in US english "insure" is actually
+    largely interchangeable with "ensure" (so says the dictionary), so I'm not
+    completely illiterate, but its definitely sub-optimal to "ensure" which is
+    non-ambiguous.
+- sql:
+  - added "fetchmany()" support to ResultProxy
+  - added support for column "key" attribute to be useable in
+    row[<key>]/row.<key>
+  - changed "BooleanExpression" to subclass from "BinaryExpression", so that
+    boolean expressions can also follow column-clause behaviors (i.e. label(),
+    etc).
+  - trailing underscores are trimmed from func.<xxx> calls, such as func.if_()
+  - fix to correlation of subqueries when the column list of the select
+    statement is constructed with individual calls to append_column(); this
+    fixes an ORM bug whereby nested select statements were not getting
+    correlated with the main select generated by the Query object.
+  - another fix to subquery correlation so that a subquery which has only one
+    FROM element will *not* correlate that single element, since at least one
+    FROM element is required in a query.
+  - default "timezone" setting is now False. this corresponds to Python's
+    datetime behavior as well as Postgres' timestamp/time types (which is the
+    only timezone-sensitive dialect at the moment) [ticket:414]
+  - the "op()" function is now treated as an "operation", rather than a
+    "comparison". the difference is, an operation produces a BinaryExpression
+    from which further operations can occur whereas comparison produces the
+    more restrictive BooleanExpression
+  - trying to redefine a reflected primary key column as non-primary key raises
+    an error
+  - type system slightly modified to support TypeDecorators that can be
+    overridden by the dialect (ok, thats not very clear, it allows the mssql
+    tweak below to be possible)
+- mssql:
+  - added an NVarchar type (produces NVARCHAR), also MSUnicode which provides
+    Unicode-translation for the NVarchar regardless of dialect convert_unicode
+    setting.
+- postgres:
+  - fix to the initial checkfirst for tables to take current schema into
+    account [ticket:424]
+  - postgres has an optional "server_side_cursors=True" flag which will utilize
+    server side cursors. these are appropriate for fetching only partial
+    results and are necessary for working with very large unbounded result
+    sets. While we'd like this to be the default behavior, different
+    environments seem to have different results and the causes have not been
+    isolated so we are leaving the feature off by default for now. Uses an
+    apparently undocumented psycopg2 behavior recently discovered on the
+    psycopg mailing list.
+  - added "BIGSERIAL" support for postgres table with
+    PGBigInteger/autoincrement
+  - fixes to postgres reflection to better handle when schema names are
+    present; thanks to jason (at) ncsmags.com [ticket:402]
+- mysql:
+  - mysql is inconsistent with what kinds of quotes it uses in foreign keys
+    during a SHOW CREATE TABLE, reflection updated to accomodate for all three
+    styles [ticket:420]
+  - mysql table create options work on a generic passthru now, i.e. Table(...,
+    mysql_engine='InnoDB', mysql_collate="latin1_german2_ci",
+    mysql_auto_increment="5", mysql_<somearg>...), helps [ticket:418]
+- firebird:
+  - order of constraint creation puts primary key first before all other
+    constraints; required for firebird, not a bad idea for others [ticket:408]
+  - Firebird fix to autoload multifield foreign keys [ticket:409]
+  - Firebird NUMERIC type properly handles a type without precision
+    [ticket:409]
+- oracle:
+  - *slight* support for binary, but still need to figure out how to insert
+    reasonably large values (over 4K). requires auto_setinputsizes=True sent to
+    create_engine(), rows must be fully fetched individually, etc.
+- orm:
+  - poked the first hole in the can of worms: saying
+    query.select_by(somerelationname=someinstance) will create the join of the
+    primary key columns represented by "somerelationname"'s mapper to the
+    actual primary key in "someinstance".
+  - reworked how relations interact with "polymorphic" mappers, i.e. mappers
+    that have a select_table as well as polymorphic flags. better determination
+    of proper join conditions, interaction with user- defined join conditions,
+    and support for self-referential polymorphic mappers.
+  - related to polymorphic mapping relations, some deeper error checking when
+    compiling relations, to detect an ambiguous "primaryjoin" in the case that
+    both sides of the relationship have foreign key references in the primary
+    join condition. also tightened down conditions used to locate "relation
+    direction", associating the "foreignkey" of the relationship with the
+    "primaryjoin"
+  - a little bit of improvement to the concept of a "concrete" inheritance
+    mapping, though that concept is not well fleshed out yet (added test case
+    to support concrete mappers on top of a polymorphic base).
+  - fix to "proxy=True" behavior on synonym()
+  - fixed bug where delete-orphan basically didn't work with many-to-many
+    relationships [ticket:427], backref presence generally hid the symptom
+  - added a mutex to the mapper compilation step. ive been reluctant to add any
+    kind of threading anything to SA but this is one spot that its its really
+    needed since mappers are typically "global", and while their state does not
+    change during normal operation, the initial compilation step does modify
+    internal state significantly, and this step usually occurs not at
+    module-level initialization time (unless you call compile()) but at
+    first-request time
+  - basic idea of "session.merge()" actually implemented.  needs more testing.
+  - added "compile_mappers()" function as a shortcut to compiling all mappers
+  - fix to MapperExtension create_instance so that entity_name properly
+    associated with new instance
+  - speed enhancements to ORM object instantiation, eager loading of rows
+  - invalid options sent to 'cascade' string will raise an exception
+    [ticket:406]
+  - fixed bug in mapper refresh/expire whereby eager loaders didnt properly
+    re-populate item lists [ticket:407]
+  - fix to post_update to ensure rows are updated even for non insert/delete
+    scenarios [ticket:413]
+  - added an error message if you actually try to modify primary key values on
+    an entity and then flush it [ticket:412]
+- extensions
+  - added "validate=False" argument to assign_mapper, if True will ensure that
+    only mapped attributes are named [ticket:426]
+  - assign_mapper gets "options", "instances" functions added (i.e.
+    MyClass.instances())
+
+0.3.3
+- string-based FROM clauses fixed, i.e. select(..., from_obj=["sometext"])
+- fixes to passive_deletes flag, lazy=None (noload) flag
+- added example/docs for dealing with large collections
+- added object_session() method to sqlalchemy namespace
+- fixed QueuePool bug whereby its better able to reconnect to a database
+that was not reachable (thanks to Sébastien Lelong), also fixed dispose()
+method
+- patch that makes MySQL rowcount work correctly! [ticket:396]
+- fix to MySQL catch of 2006/2014 errors to properly re-raise OperationalError
+exception
+
+0.3.2
+- major connection pool bug fixed.  fixes MySQL out of sync
+errors, will also prevent transactions getting rolled back
+accidentally in all DBs [ticket:387]
+- major speed enhancements vs. 0.3.1, to bring speed
+back to 0.2.8 levels
+  - made conditional dozens of debug log calls that were
+  time-intensive to generate log messages
+  - fixed bug in cascade rules whereby the entire object graph
+  could be unnecessarily cascaded on the save/update cascade
+  - various speedups in attributes module
+- identity map in Session is by default *no longer weak referencing*.
+to have it be weak referencing, use create_session(weak_identity_map=True)
+fixes [ticket:388]
+- MySQL detects errors 2006 (server has gone away) and 2014
+(commands out of sync) and invalidates the connection on which it occured.
+- MySQL bool type fix: [ticket:307]
+- postgres reflection fixes: [ticket:349] [ticket:382]
+- added keywords for EXCEPT, INTERSECT, EXCEPT ALL, INTERSECT ALL
+[ticket:247]
+- assign_mapper in assignmapper extension returns the created mapper
+[changeset:2110]
+- added label() function to Select class, when scalar=True is used
+to create a scalar subquery
+i.e. "select x, y, (select max(foo) from table) AS foomax from table"
+- added onupdate and ondelete keyword arguments to ForeignKey; propagate
+to underlying ForeignKeyConstraint if present.  (dont propagate in the
+other direction, however)
+- fix to session.update() to preserve "dirty" status of incoming object
+- sending a selectable to an IN via the in_() function no longer creates
+a "union" out of multiple selects; only one selectable to a the in_() function
+is allowed now (make a union yourself if union is needed)
+- improved support for disabling save-update cascade via cascade="none" etc.
+- added "remote_side" argument to relation(), used only with self-referential
+mappers to force the direction of the parent/child relationship.  replaces
+the usage of the "foreignkey" parameter for "switching" the direction.
+"foreignkey" argument is deprecated for all uses and will eventually
+be replaced by an argument dedicated to ForeignKey specification on mappers.
+
+0.3.1
+- Engine/Pool:
+  - some new Pool utility classes, updated docs
+  - "use_threadlocal" on Pool defaults to False (same as create_engine)
+  - fixed direct execution of Compiled objects
+  - create_engine() reworked to be strict about incoming **kwargs.  all keyword
+arguments must be consumed by one of the dialect, connection pool, and engine
+constructors, else a TypeError is thrown which describes the full set of
+invalid kwargs in relation to the selected dialect/pool/engine configuration.
+- Databases/Types:
+  - MySQL catches exception on "describe" and reports as NoSuchTableError
+  - further fixes to sqlite booleans, weren't working as defaults
+  - fix to postgres sequence quoting when using schemas
+- ORM:
+  - the "delete" cascade will load in all child objects, if they were not
+loaded already.  this can be turned off (i.e. the old behavior) by setting
+passive_deletes=True on a relation().
+  - adjustments to reworked eager query generation to not fail on circular
+eager-loaded relationships (like backrefs)
+  - fixed bug where eagerload() (nor lazyload()) option didn't properly
+instruct the Query whether or not to use "nesting" when producing a
+LIMIT query.
+  - fixed bug in circular dependency sorting at flush time; if object A
+contained a cyclical many-to-one relationship to object B, and object B
+was just attached to object A, *but* object B itself wasnt changed,
+the many-to-one synchronize of B's primary key attribute to A's foreign key
+attribute wouldnt occur.  [ticket:360]
+  - implemented from_obj argument for query.count, improves count function
+on selectresults [ticket:325]
+  - added an assertion within the "cascade" step of ORM relationships to check
+that the class of object attached to a parent object is appropriate
+(i.e. if A.items stores B objects, raise an error if a C is appended to A.items)
+  - new extension sqlalchemy.ext.associationproxy, provides transparent
+"association object" mappings.  new example
+examples/association/proxied_association.py illustrates.
+  - improvement to single table inheritance to load full hierarchies beneath
+the target class
+  - fix to subtle condition in topological sort where a node could appear twice,
+for [ticket:362]
+  - additional rework to topological sort, refactoring, for [ticket:365]
+  - "delete-orphan" for a certain type can be set on more than one parent class;
+the instance is an "orphan" only if its not attached to *any* of those parents
+
+0.3.0
+- General:
+    - logging is now implemented via standard python "logging" module.
+    "echo" keyword parameters are still functional but set/unset
+    log levels for their respective classes/instances.  all logging
+    can be controlled directly through the Python API by setting
+    INFO and DEBUG levels for loggers in the "sqlalchemy" namespace.
+    class-level logging is under "sqlalchemy.<module>.<classname>",
+    instance-level logging under "sqlalchemy.<module>.<classname>.0x..<00-FF>".
+    Test suite includes "--log-info" and "--log-debug" arguments
+    which work independently of --verbose/--quiet.  Logging added
+    to orm to allow tracking of mapper configurations, row iteration.
+    - the documentation-generation system has been overhauled to be
+    much simpler in design and more integrated with Markdown
+- Specific Databases:
+    - SQLite:
+    - sqlite boolean datatype converts False/True to 0/1 by default
+    - fixes to Date/Time (SLDate/SLTime) types; works as good as postgres
+    now [ticket:335]
+    - MS-SQL:
+    - fixes bug 261 (table reflection broken for MS-SQL case-sensitive
+    databases)
+    - can now specify port for pymssql
+    - introduces new "auto_identity_insert" option for auto-switching
+    between "SET IDENTITY_INSERT" mode when values specified for IDENTITY columns
+    - now supports multi-column foreign keys
+    - fix to reflecting date/datetime columns
+    - NCHAR and NVARCHAR type support added
+    - Oracle:
+    - Oracle has experimental support for cx_Oracle.TIMESTAMP, which requires
+    a setinputsizes() call on the cursor that is now enabled via the
+    'auto_setinputsizes' flag to the oracle dialect.
+    - Firebird:
+    - aliases do not use "AS"
+    - correctly raises NoSuchTableError when reflecting non-existent table
+- Schema:
+    - a fair amount of cleanup to the schema package, removal of ambiguous
+    methods, methods that are no longer needed.  slightly more constrained
+    useage, greater emphasis on explicitness
+    - the "primary_key" attribute of Table and other selectables becomes
+    a setlike ColumnCollection object; is ordered but not numerically
+    indexed.  a comparison clause between two pks that are derived from the
+    same underlying tables (i.e. such as two Alias objects) can be generated
+    via table1.primary_key==table2.primary_key
+    - ForeignKey(Constraint) supports "use_alter=True", to create/drop a foreign key
+    via ALTER.  this allows circular foreign key relationships to be set up.
+    - append_item() methods removed from Table and Column; preferably
+    construct Table/Column/related objects inline, but if needed use
+    append_column(), append_foreign_key(), append_constraint(), etc.
+    - table.create() no longer returns the Table object, instead has no
+    return value.  the usual case is that tables are created via metadata,
+    which is preferable since it will handle table dependencies.
+    - added UniqueConstraint (goes at Table level), CheckConstraint
+    (goes at Table or Column level).
+    - index=False/unique=True on Column now creates a UniqueConstraint,
+    index=True/unique=False creates a plain Index,
+    index=True/unique=True on Column creates a unique Index.  'index'
+    and 'unique' keyword arguments to column are now boolean only; for
+    explcit names and groupings of indexes or unique constraints, use the
+    UniqueConstraint/Index constructs explicitly.
+    - added autoincrement=True to Column; will disable schema generation
+    of SERIAL/AUTO_INCREMENT/identity seq for postgres/mysql/mssql if
+    explicitly set to False
+    - TypeEngine objects now have methods to deal with copying and comparing
+    values of their specific type.  Currently used by the ORM, see below.
+    - fixed condition that occurred during reflection when a primary key
+    column was explciitly overridden, where the PrimaryKeyConstraint would
+    get both the reflected and the programmatic column doubled up
+    - the "foreign_key" attribute on Column and ColumnElement in general
+    is deprecated, in favor of the "foreign_keys" list/set-based attribute,
+    which takes into account multiple foreign keys on one column.
+    "foreign_key" will return the first element in the "foreign_keys" list/set
+    or None if the list is empty.
+- Connections/Pooling/Execution:
+    - connection pool tracks open cursors and automatically closes them
+    if connection is returned to pool with cursors still opened.  Can be
+    affected by options which cause it to raise an error instead, or to
+    do nothing.  fixes issues with MySQL, others
+    - fixed bug where Connection wouldnt lose its Transaction
+    after commit/rollback
+    - added scalar() method to ComposedSQLEngine, ResultProxy
+    - ResultProxy will close() the underlying cursor when the ResultProxy
+    itself is closed.  this will auto-close cursors for ResultProxy objects
+    that have had all their rows fetched (or had scalar() called).
+    - ResultProxy.fetchall() internally uses DBAPI fetchall() for better efficiency,
+    added to mapper iteration as well (courtesy Michael Twomey)
+- SQL Construction:
+    - changed "for_update" parameter to accept False/True/"nowait"
+    and "read", the latter two of which are interpreted only by
+    Oracle and Mysql [ticket:292]
+    - added extract() function to sql dialect
+    (SELECT extract(field FROM expr))
+    - BooleanExpression includes new "negate" argument to specify
+    the appropriate negation operator if one is available.
+    - calling a negation on an "IN" or "IS" clause will result in
+    "NOT IN", "IS NOT" (as opposed to NOT (x IN y)).
+    - Function objects know what to do in a FROM clause now.  their
+    behavior should be the same, except now you can also do things like
+    select(['*'], from_obj=[func.my_function()]) to get multiple
+    columns from the result, or even use sql.column() constructs to name the
+    return columns [ticket:172]
+- ORM:
+    - attribute tracking modified to be more intelligent about detecting
+    changes, particularly with mutable types.  TypeEngine objects now
+    take a greater role in defining how to compare two scalar instances,
+    including the addition of a MutableType mixin which is implemented by
+    PickleType.  unit-of-work now tracks the "dirty" list as an expression
+    of all persistent objects where the attribute manager detects changes.
+    The basic issue thats fixed is detecting changes on PickleType
+    objects, but also generalizes type handling and "modified" object
+    checking to be more complete and extensible.
+    - a wide refactoring to "attribute loader" and "options" architectures.
+    ColumnProperty and PropertyLoader define their loading behaivor via switchable
+    "strategies", and MapperOptions no longer use mapper/property copying
+    in order to function; they are instead propagated via QueryContext
+    and SelectionContext objects at query/instances time.
+    All of the internal copying of mappers and properties that was used to handle
+    inheritance as well as options() has been removed; the structure
+    of mappers and properties is much simpler than before and is clearly laid out
+    in the new 'interfaces' module.
+    - related to the mapper/property overhaul, internal refactoring to
+    mapper instances() method to use a SelectionContext object to track
+    state during the operation.
+    SLIGHT API BREAKAGE: the append_result() and populate_instances()
+    methods on MapperExtension have a slightly different method signature
+    now as a result of the change; hoping that these methods are not
+    in widespread use as of yet.
+    - instances() method moved to Query now, backwards-compatible
+    version remains on Mapper.
+    - added contains_eager() MapperOption, used in conjunction with
+    instances() to specify properties that should be eagerly loaded
+    from the result set, using their plain column names by default, or translated
+    given an custom row-translation function.
+    - more rearrangements of unit-of-work commit scheme to better allow
+    dependencies within circular flushes to work properly...updated
+    task traversal/logging implementation
+    - polymorphic mappers (i.e. using inheritance) now produces INSERT
+    statements in order of tables across all inherited classes
+    [ticket:321]
+    - added an automatic "row switch" feature to mapping, which will
+    detect a pending instance/deleted instance pair with the same
+    identity key and convert the INSERT/DELETE to a single UPDATE
+    - "association" mappings simplified to take advantage of
+    automatic "row switch" feature
+    - "custom list classes" is now implemented via the "collection_class"
+    keyword argument to relation().  the old way still works but is
+    deprecated [ticket:212]
+    - added "viewonly" flag to relation(), allows construction of
+    relations that have no effect on the flush() process.
+    - added "lockmode" argument to base Query select/get functions,
+    including "with_lockmode" function to get a Query copy that has
+    a default locking mode.  Will translate "read"/"update"
+    arguments into a for_update argument on the select side.
+    [ticket:292]
+    - implemented "version check" logic in Query/Mapper, used
+    when version_id_col is in effect and query.with_lockmode()
+    is used to get() an instance thats already loaded
+    - post_update behavior improved; does a better job at not
+    updating too many rows, updates only required columns
+    [ticket:208]
+    - adjustments to eager loading so that its "eager chain" is
+    kept separate from the normal mapper setup, thereby
+    preventing conflicts with lazy loader operation, fixes
+    [ticket:308]
+    - fix to deferred group loading
+    - session.flush() wont close a connection it opened [ticket:346]
+    - added "batch=True" flag to mapper; if False, save_obj
+    will fully save one object at a time including calls
+    to before_XXXX and after_XXXX
+    - added "column_prefix=None" argument to mapper; prepends the
+    given string (typically '_') to column-based attributes automatically
+    set up from the mapper's Table
+    - specifying joins in the from_obj argument of query.select() will
+    replace the main table of the query, if the table is somewhere within
+    the given from_obj.  this makes it possible to produce custom joins and
+    outerjoins in queries without the main table getting added twice.
+    [ticket:315]
+    - eagerloading is adjusted to more thoughtfully attach its LEFT OUTER JOINs
+    to the given query, looking for custom "FROM" clauses that may have
+    already been set up.
+    - added join_to and outerjoin_to transformative methods to SelectResults,
+    to build up join/outerjoin conditions based on property names. also
+    added select_from to explicitly set from_obj parameter.
+    - removed "is_primary" flag from mapper.
+
+0.2.8
+- cleanup on connection methods + documentation.  custom DBAPI
+arguments specified in query string, 'connect_args' argument
+to 'create_engine', or custom creation function via 'creator'
+function to 'create_engine'.
+- added "recycle" argument to Pool, is "pool_recycle" on create_engine,
+defaults to 3600 seconds; connections after this age will be closed and
+replaced with a new one, to handle db's that automatically close
+stale connections [ticket:274]
+- changed "invalidate" semantics with pooled connection; will
+instruct the underlying connection record to reconnect the next
+time its called.  "invalidate" will also automatically be called
+if any error is thrown in the underlying call to connection.cursor().
+this will hopefully allow the connection pool to reconnect to a
+database that had been stopped and started without restarting
+the connecting application [ticket:121]
+- eesh !  the tutorial doctest was broken for quite some time.
+- add_property() method on mapper does a "compile all mappers"
+step in case the given property references a non-compiled mapper
+(as it did in the case of the tutorial !)
+- [ticket:277] check for pg sequence already existing before create
+- if a contextual session is established via MapperExtension.get_session
+(as it is using the sessioncontext plugin, etc), a lazy load operation
+will use that session by default if the parent object is not
+persistent with a session already.
+- lazy loads will not fire off for an object that does not have a
+database identity (why?
+see http://www.sqlalchemy.org/trac/wiki/WhyDontForeignKeysLoadData)
+- unit-of-work does a better check for "orphaned" objects that are
+part of a "delete-orphan" cascade, for certain conditions where the
+parent isnt available to cascade from.
+- mappers can tell if one of their objects is an "orphan" based
+on interactions with the attribute package. this check is based
+on a status flag maintained for each relationship
+when objects are attached and detached from each other.
+- it is now invalid to declare a self-referential relationship with
+"delete-orphan" (as the abovementioned check would make them impossible
+to save)
+- improved the check for objects being part of a session when the
+unit of work seeks to flush() them as part of a relationship..
+- [ticket:280] statement execution supports using the same BindParam
+object more than once in an expression; simplified handling of positional
+parameters.  nice job by Bill Noon figuring out the basic idea.
+- postgres reflection moved to use pg_schema tables, can be overridden
+with use_information_schema=True argument to create_engine
+[ticket:60], [ticket:71]
+- added case_sensitive argument to MetaData, Table, Column, determines
+itself automatically based on if a parent schemaitem has a non-None
+setting for the flag, or if not, then whether the identifier name is all lower
+case or not.  when set to True, quoting is applied to identifiers with mixed or
+uppercase identifiers.  quoting is also applied automatically in all cases to
+identifiers that are known to be reserved words or contain other non-standard
+characters. various database dialects can override all of this behavior, but
+currently they are all using the default behavior.  tested with postgres, mysql,
+sqlite, oracle.  needs more testing with firebird, ms-sql. part of the ongoing
+work with [ticket:155]
+- unit tests updated to run without any pysqlite installed; pool
+test uses a mock DBAPI
+- urls support escaped characters in passwords [ticket:281]
+- added limit/offset to UNION queries (though not yet in oracle)
+- added "timezone=True" flag to DateTime and Time types.  postgres
+so far will convert this to "TIME[STAMP] (WITH|WITHOUT) TIME ZONE",
+so that control over timezone presence is more controllable (psycopg2
+returns datetimes with tzinfo's if available, which can create confusion
+against datetimes that dont).
+- fix to using query.count() with distinct, **kwargs with SelectResults
+count() [ticket:287]
+- deregister Table from MetaData when autoload fails; [ticket:289]
+- import of py2.5s sqlite3 [ticket:293]
+- unicode fix for startswith()/endswith() [ticket:296]
+
+0.2.7
+- quoting facilities set up so that database-specific quoting can be
+turned on for individual table, schema, and column identifiers when
+used in all queries/creates/drops.  Enabled via "quote=True" in
+Table or Column, as well as "quote_schema=True" in Table.  Thanks to
+Aaron Spike for his excellent efforts.
+- assignmapper was setting is_primary=True, causing all sorts of mayhem
+by not raising an error when redundant mappers were set up, fixed
+- added allow_null_pks option to Mapper, allows rows where some
+primary key columns are null (i.e. when mapping to outer joins etc)
+- modifcation to unitofwork to not maintain ordering within the
+"new" list or within the UOWTask "objects" list; instead, new objects
+are tagged with an ordering identifier as they are registered as new
+with the session, and the INSERT statements are then sorted within the
+mapper save_obj.  the INSERT ordering has basically been pushed all
+the way to the end of the flush cycle. that way the various sorts and
+organizations occuring within UOWTask (particularly the circular task
+sort) dont have to worry about maintaining order (which they werent anyway)
+- fixed reflection of foreign keys to autoload the referenced table
+if it was not loaded already
+- [ticket:256] - pass URL query string arguments to connect() function
+- [ticket:257] - oracle boolean type
+- custom primary/secondary join conditions in a relation *will* be propagated
+to backrefs by default.  specifying a backref() will override this behavior.
+- better check for ambiguous join conditions in sql.Join; propagates to a
+better error message in PropertyLoader (i.e. relation()/backref()) for when
+the join condition can't be reasonably determined.
+- sqlite creates ForeignKeyConstraint objects properly upon table
+reflection.
+- adjustments to pool stemming from changes made for [ticket:224].
+overflow counter should only be decremented if the connection actually
+succeeded.  added a test script to attempt testing this.
+- fixed mysql reflection of default values to be PassiveDefault
+- added reflected 'tinyint', 'mediumint' type to MS-SQL [ticket:263],
+[ticket:264]
+- SingletonThreadPool has a size and does a cleanup pass, so that
+only a given number of thread-local connections stay around (needed
+for sqlite applications that dispose of threads en masse)
+- fixed small pickle bug(s) with lazy loaders [ticket:265] [ticket:267]
+- fixed possible error in mysql reflection where certain versions
+return an array instead of string for SHOW CREATE TABLE call
+- fix to lazy loads when mapping to joins [changeset:1770]
+- all create()/drop() calls have a keyword argument of "connectable".
+"engine" is deprecated.
+- fixed ms-sql connect() to work with adodbapi
+- added "nowait" flag to Select()
+- inheritance check uses issubclass() instead of direct __mro__ check
+to make sure class A inherits from B, allowing mapper inheritance to more
+flexibly correspond to class inheritance [ticket:271]
+- SelectResults will use a subselect, when calling an aggregate (i.e.
+max, min, etc.) on a SelectResults that has an ORDER BY clause
+[ticket:252]
+- fixes to types so that database-specific types more easily used;
+fixes to mysql text types to work with this methodology
+[ticket:269]
+- some fixes to sqlite date type organization
+- added MSTinyInteger to MS-SQL [ticket:263]
+
+0.2.6
+- big overhaul to schema to allow truly composite primary and foreign
+key constraints, via new ForeignKeyConstraint and PrimaryKeyConstraint
+objects.
+Existing methods of primary/foreign key creation have not been changed
+but use these new objects behind the scenes.  table creation
+and reflection is now more table oriented rather than column oriented.
+[ticket:76]
+- overhaul to MapperExtension calling scheme, wasnt working very well
+previously
+- tweaks to ActiveMapper, supports self-referential relationships
+- slight rearrangement to objectstore (in activemapper/threadlocal)
+so that the SessionContext is referenced by '.context' instead
+of subclassed directly.
+- activemapper will use threadlocal's objectstore if the mod is
+activated when activemapper is imported
+- small fix to URL regexp to allow filenames with '@' in them
+- fixes to Session expunge/update/etc...needs more cleanup.
+- select_table mappers *still* werent always compiling
+- fixed up Boolean datatype
+- added count()/count_by() to list of methods proxied by assignmapper;
+this also adds them to activemapper
+- connection exceptions wrapped in DBAPIError
+- ActiveMapper now supports autoloading column definitions from the
+database if you supply a __autoload__ = True attribute in your
+mapping inner-class.  Currently this does not support reflecting
+any relationships.
+- deferred column load could screw up the connection status in
+a flush() under some circumstances, this was fixed
+- expunge() was not working with cascade, fixed.
+- potential endless loop in cascading operations fixed.
+- added "synonym()" function, applied to properties to have a
+propname the same as another, for the purposes of overriding props
+and allowing the original propname to be accessible in select_by().
+- fix to typing in clause construction which specifically helps
+type issues with polymorphic_union (CAST/ColumnClause propagates
+its type to proxy columns)
+- mapper compilation work ongoing, someday it'll work....moved
+around the initialization of MapperProperty objects to be after
+all mappers are created to better handle circular compilations.
+do_init() method is called on all properties now which are more
+aware of their "inherited" status if so.
+- eager loads explicitly disallowed on self-referential relationships, or
+relationships to an inheriting mapper (which is also self-referential)
+- reduced bind param size in query._get to appease the picky oracle
+[ticket:244]
+- added 'checkfirst' argument to table.create()/table.drop(), as
+well as table.exists() [ticket:234]
+- some other ongoing fixes to inheritance [ticket:245]
+- attribute/backref/orphan/history-tracking tweaks as usual...
+
+0.2.5
+- fixed endless loop bug in select_by(), if the traversal hit
+two mappers that referenced each other
+- upgraded all unittests to insert './lib/' into sys.path,
+working around new setuptools PYTHONPATH-killing behavior
+- further fixes with attributes/dependencies/etc....
+- improved error handling for when DynamicMetaData is not connected
+- MS-SQL support largely working (tested with pymssql)
+- ordering of UPDATE and DELETE statements within groups is now
+in order of primary key values, for more deterministic ordering
+- after_insert/delete/update mapper extensions now called per object,
+not per-object-per-table
+- further fixes/refactorings to mapper compilation
+
+0.2.4
+- try/except when the mapper sets init.__name__ on a mapped class,
+supports python 2.3
+- fixed bug where threadlocal engine would still autocommit
+despite a transaction in progress
+- lazy load and deferred load operations require the parent object
+to be in a Session to do the operation; whereas before the operation
+would just return a blank list or None, it now raises an exception.
+- Session.update() is slightly more lenient if the session to which
+the given object was formerly attached to was garbage collected;
+otherwise still requires you explicitly remove the instance from
+the previous Session.
+- fixes to mapper compilation, checking for more error conditions
+- small fix to eager loading combined with ordering/limit/offset
+- utterly remarkable:  added a single space between 'CREATE TABLE'
+and '(<the rest of it>' since *thats how MySQL indicates a non-
+reserved word tablename.....* [ticket:206]
+- more fixes to inheritance, related to many-to-many relations
+properly saving
+- fixed bug when specifying explicit module to mysql dialect
+- when QueuePool times out it raises a TimeoutError instead of
+erroneously making another connection
+- Queue.Queue usage in pool has been replaced with a locally
+modified version (works in py2.3/2.4!) that uses a threading.RLock
+for a mutex.  this is to fix a reported case where a ConnectionFairy's
+__del__() method got called within the Queue's get() method, which
+then returns its connection to the Queue via the the put() method,
+causing a reentrant hang unless threading.RLock is used.
+- postgres will not place SERIAL keyword on a primary key column
+if it has a foreign key constraint
+- cursor() method on ConnectionFairy allows db-specific extension
+arguments to be propagated [ticket:221]
+- lazy load bind params properly propagate column type [ticket:225]
+- new MySQL types: MSEnum, MSTinyText, MSMediumText, MSLongText, etc.
+more support for MS-specific length/precision params in numeric types
+patch courtesy Mike Bernson
+- some fixes to connection pool invalidate() [ticket:224]
+
+0.2.3
+- overhaul to mapper compilation to be deferred.  this allows mappers
+to be constructed in any order, and their relationships to each
+other are compiled when the mappers are first used.
+- fixed a pretty big speed bottleneck in cascading behavior particularly
+when backrefs were in use
+- the attribute instrumentation module has been completely rewritten; its
+now a large degree simpler and clearer, slightly faster.  the "history"
+of an attribute is no longer micromanaged with each change and is
+instead part of a "CommittedState" object created when the
+instance is first loaded.  HistoryArraySet is gone, the behavior of
+list attributes is now more open ended (i.e. theyre not sets anymore).
+- py2.4 "set" construct used internally, falls back to sets.Set when
+"set" not available/ordering is needed.
+- fix to transaction control, so that repeated rollback() calls
+dont fail (was failing pretty badly when flush() would raise
+an exception in a larger try/except transaction block)
+- "foreignkey" argument to relation() can also be a list.  fixed
+auto-foreignkey detection [ticket:151]
+- fixed bug where tables with schema names werent getting indexed in
+the MetaData object properly
+- fixed bug where Column with redefined "key" property wasnt getting
+type conversion happening in the ResultProxy [ticket:207]
+- fixed 'port' attribute of URL to be an integer if present
+- fixed old bug where if a many-to-many table mapped as "secondary"
+had extra columns, delete operations didnt work
+- bugfixes for mapping against UNION queries
+- fixed incorrect exception class thrown when no DB driver present
+- added NonExistentTable exception thrown when reflecting a table
+that doesnt exist [ticket:138]
+- small fix to ActiveMapper regarding one-to-one backrefs, other
+refactorings
+- overridden constructor in mapped classes gets __name__ and
+__doc__ from the original class
+- fixed small bug in selectresult.py regarding mapper extension
+[ticket:200]
+- small tweak to cascade_mappers, not very strongly supported
+function at the moment
+- some fixes to between(), column.between() to propagate typing
+information better [ticket:202]
+- if an object fails to be constructed, is not added to the
+session [ticket:203]
+- CAST function has been made into its own clause object with
+its own compilation function in ansicompiler; allows MySQL
+to silently ignore most CAST calls since MySQL
+seems to only support the standard CAST syntax with Date types.
+MySQL-compatible CAST support for strings, ints, etc. a TODO
+
+0.2.2
+- big improvements to polymorphic inheritance behavior, enabling it
+to work with adjacency list table structures [ticket:190]
+- major fixes and refactorings to inheritance relationships overall,
+more unit tests
+- fixed "echo_pool" flag on create_engine()
+- fix to docs, removed incorrect info that close() is unsafe to use
+with threadlocal strategy (its totally safe !)
+- create_engine() can take URLs as string or unicode [ticket:188]
+- firebird support partially completed;
+thanks to James Ralston and Brad Clements for their efforts.
+- Oracle url translation was broken, fixed, will feed host/port/sid
+into cx_oracle makedsn() if 'database' field is present, else uses
+straight TNS name from the 'host' field
+- fix to using unicode criterion for query.get()/query.load()
+- count() function on selectables now uses table primary key or
+first column instead of "1" for criterion, also uses label "rowcount"
+instead of "count".
+- got rudimental "mapping to multiple tables" functionality cleaned up,
+more correctly documented
+- restored global_connect() function, attaches to a DynamicMetaData
+instance called "default_metadata".  leaving MetaData arg to Table
+out will use the default metadata.
+- fixes to session cascade behavior, entity_name propigation
+- reorganized unittests into subdirectories
+- more fixes to threadlocal connection nesting patterns
+
+0.2.1
+- "pool" argument to create_engine() properly propagates
+- fixes to URL, raises exception if not parsed, does not pass blank
+fields along to the DB connect string (a string such as
+user:host@/db was breaking on postgres)
+- small fixes to Mapper when it inserts and tries to get
+new primary key values back
+- rewrote half of TLEngine, the ComposedSQLEngine used with
+'strategy="threadlocal"'.  it now properly implements engine.begin()/
+engine.commit(), which nest fully with connection.begin()/trans.commit().
+added about six unittests.
+- major "duh" in pool.Pool, forgot to put back the WeakValueDictionary.
+unittest which was supposed to check for this was also silently missing
+it.  fixed unittest to ensure that ConnectionFairy properly falls out
+of scope.
+- placeholder dispose() method added to SingletonThreadPool, doesnt
+do anything yet
+- rollback() is automatically called when an exception is raised,
+but only if theres no transaction in process (i.e. works more like
+autocommit).
+- fixed exception raise in sqlite if no sqlite module present
+- added extra example detail for association object doc
+- Connection adds checks for already being closed
+
+0.2.0
+- overhaul to Engine system so that what was formerly the SQLEngine
+is now a ComposedSQLEngine which consists of a variety of components,
+including a Dialect, ConnectionProvider, etc. This impacted all the
+db modules as well as Session and Mapper.
+- create_engine now takes only RFC-1738-style strings:
+driver://user:password@host:port/database
+- total rewrite of connection-scoping methodology, Connection objects
+can now execute clause elements directly, added explicit "close" as
+well as support throughout Engine/ORM to handle closing properly,
+no longer relying upon __del__ internally to return connections
+to the pool [ticket:152].
+- overhaul to Session interface and scoping.  uses hibernate-style
+methods, including query(class), save(), save_or_update(), etc.
+no threadlocal scope is installed by default.  Provides a binding
+interface to specific Engines and/or Connections so that underlying
+Schema objects do not need to be bound to an Engine.  Added a basic
+SessionTransaction object that can simplistically aggregate transactions
+across multiple engines.
+- overhaul to mapper's dependency and "cascade" behavior; dependency logic
+factored out of properties.py into a separate module "dependency.py".
+"cascade" behavior is now explicitly controllable, proper implementation
+of "delete", "delete-orphan", etc.  dependency system can now determine at
+flush time if a child object has a parent or not so that it makes better
+decisions on how that child should be updated in the DB with regards to deletes.
+- overhaul to Schema to build upon MetaData object instead of an Engine.
+Entire SQL/Schema system can be used with no Engines whatsoever, executed
+solely by an explicit Connection object.  the "bound" methodlogy exists via the
+BoundMetaData for schema objects.  ProxyEngine is generally not needed
+anymore and is replaced by DynamicMetaData.
+- true polymorphic behavior implemented, fixes [ticket:167]
+- "oid" system has been totally moved into compile-time behavior;
+if they are used in an order_by where they are not available, the order_by
+doesnt get compiled, fixes [ticket:147]
+- overhaul to packaging; "mapping" is now "orm", "objectstore" is now
+"session", the old "objectstore" namespace gets loaded in via the
+"threadlocal" mod if used
+- mods now called in via "import <modname>".  extensions favored over
+mods as mods are globally-monkeypatching
+- fix to add_property so that it propagates properties to inheriting
+mappers [ticket:154]
+- backrefs create themselves against primary mapper of its originating
+property, priamry/secondary join arguments can be specified to override.
+helps their usage with polymorphic mappers
+- "table exists" function has been implemented [ticket:31]
+- "create_all/drop_all" added to MetaData object [ticket:98]
+- improvements and fixes to topological sort algorithm, as well as more
+unit tests
+- tutorial page added to docs which also can be run with a custom doctest
+runner to ensure its properly working.  docs generally overhauled to
+deal with new code patterns
+- many more fixes, refactorings.
+- migration guide is available on the Wiki at
+http://www.sqlalchemy.org/trac/wiki/02Migration
+
+0.1.7
+- some fixes to topological sort algorithm
+- added DISTINCT ON support to Postgres (just supply distinct=[col1,col2..])
+- added __mod__ (% operator) to sql expressions
+- "order_by" mapper property inherited from inheriting mapper
+- fix to column type used when mapper UPDATES/DELETEs
+- with convert_unicode=True, reflection was failing, has been fixed
+- types types types!  still werent working....have to use TypeDecorator again :(
+- mysql binary type converts array output to buffer, fixes PickleType
+- fixed the attributes.py memory leak once and for all
+- unittests are qualified based on the databases that support each one
+- fixed bug where column defaults would clobber VALUES clause of insert objects
+- fixed bug where table def w/ schema name would force engine connection
+- fix for parenthesis to work correctly with subqueries in INSERT/UPDATE
+- HistoryArraySet gets extend() method
+- fixed lazyload support for other comparison operators besides =
+- lazyload fix where two comparisons in the join condition point to the
+samem column
+- added "construct_new" flag to mapper, will use __new__ to create instances
+instead of __init__ (standard in 0.2)
+- added selectresults.py to SVN, missed it last time
+- tweak to allow a many-to-many relationship from a table to itself via
+an association table
+- small fix to "translate_row" function used by polymorphic example
+- create_engine uses cgi.parse_qsl to read query string (out the window in 0.2)
+- tweaks to CAST operator
+- fixed function names LOCAL_TIME/LOCAL_TIMESTAMP -> LOCALTIME/LOCALTIMESTAMP
+- fixed order of ORDER BY/HAVING in compile
+
+0.1.6
+- support for MS-SQL added courtesy Rick Morrison, Runar Petursson
+- the latest SQLSoup from J. Ellis
+- ActiveMapper has preliminary support for inheritance (Jeff Watkins)
+- added a "mods" system which allows pluggable modules that modify/augment
+core functionality, using the function "install_mods(*modnames)".
+- added the first "mod", SelectResults, which modifies mapper selects to
+return generators that turn ranges into LIMIT/OFFSET queries (Jonas Borgstr?- factored out querying capabilities of Mapper into a separate Query object
+which is Session-centric.  this improves the performance of mapper.using(session)
+and makes other things possible.
+- objectstore/Session refactored, the official way to save objects is now
+via the flush() method.  The begin/commit functionality of Session is factored
+into LegacySession which is still established as the default behavior, until
+the 0.2 series.
+- types system is bound to an engine at query compile time, not schema
+construction time.  this simplifies the types system as well as the ProxyEngine.
+- added 'version_id' keyword argument to mapper. this keyword should reference a
+Column object with type Integer, preferably non-nullable, which will be used on
+the mapped table to track version numbers. this number is incremented on each
+save operation and is specifed in the UPDATE/DELETE conditions so that it
+factors into the returned row count, which results in a ConcurrencyError if the
+value received is not the expected count.
+- added 'entity_name' keyword argument to mapper. a mapper is now associated
+with a class via the class object as well as an optional entity_name parameter,
+which is a string defaulting to None. any number of primary mappers can be
+created for a class, qualified by the entity name. instances of those classes
+will issue all of their load and save operations through their
+entity_name-qualified mapper, and maintain separate a identity in the identity
+map for an otherwise equilvalent object.
+- overhaul to the attributes system. code has been clarified, and also fixed to
+support proper polymorphic behavior on object attributes.
+- added "for_update" flag to Select objects
+- some fixes for backrefs
+- fix for postgres1 DateTime type
+- documentation pages mostly switched over to Markdown syntax
+
+0.1.5
+- added SQLSession concept to SQLEngine. this object keeps track of retrieving a
+connection from the connection pool as well as an in-progress transaction.
+methods push_session() and pop_session() added to SQLEngine which push/pop a new
+SQLSession onto the engine, allowing operation upon a second connection "nested"
+within the previous one, allowing nested transactions. Other tricks are sure to
+come later regarding SQLSession.
+- added nest_on argument to objectstore.Session. This is a single SQLEngine or
+list of engines for which push_session()/pop_session() will be called each time
+this Session becomes the active session (via objectstore.push_session() or
+equivalent). This allows a unit of work Session to take advantage of the nested
+transaction feature without explicitly calling push_session/pop_session on the
+engine.
+- factored apart objectstore/unitofwork to separate "Session scoping" from
+"uow commit heavy lifting"
+- added populate_instance() method to MapperExtension. allows an extension to
+modify the population of object attributes. this method can call the
+populate_instance() method on another mapper to proxy the attribute population
+from one mapper to another; some row translation logic is also built in to help
+with this.
+- fixed Oracle8-compatibility "use_ansi" flag which converts JOINs to
+comparisons with the = and (+) operators, passes basic unittests
+- tweaks to Oracle LIMIT/OFFSET support
+- Oracle reflection uses ALL_** views instead of USER_** to get larger
+list of stuff to reflect from
+- fixes to Oracle foreign key reflection [ticket:105]
+- objectstore.commit(obj1, obj2,...) adds an extra step to seek out private
+relations on properties and delete child objects, even though its not a global
+commit
+- lots and lots of fixes to mappers which use inheritance, strengthened the
+concept of relations on a mapper being made towards the "local" table for that
+mapper, not the tables it inherits.  allows more complex compositional patterns
+to work with lazy/eager loading.
+- added support for mappers to inherit from others based on the same table,
+just specify the same table as that of both parent/child mapper.
+- some minor speed improvements to the attributes system with regards to
+instantiating and populating new objects.
+- fixed MySQL binary unit test
+- INSERTs can receive clause elements as VALUES arguments, not just literal
+values
+- support for calling multi-tokened functions, i.e. schema.mypkg.func()
+- added J. Ellis' SQLSoup module to extensions package
+- added "polymorphic" examples illustrating methods to load multiple object types
+from one mapper, the second of which uses the new populate_instance() method.
+small improvements to mapper, UNION construct to help the examples along
+- improvements/fixes to session.refresh()/session.expire() (which may have
+been called "invalidate" earlier..)
+- added session.expunge() which totally removes an object from the current
+session
+- added *args, **kwargs pass-thru to engine.transaction(func) allowing easier
+creation of transactionalizing decorator functions
+- added iterator interface to ResultProxy:  "for row in result:..."
+- added assertion to tx = session.begin(); tx.rollback(); tx.begin(), i.e. cant
+use it after a rollback()
+- added date conversion on bind parameter fix to SQLite enabling dates to
+work with pysqlite1
+- improvements to subqueries to more intelligently construct their FROM
+clauses [ticket:116]
+- added PickleType to types.
+- fixed two bugs with column labels with regards to bind parameters: bind param
+keynames they are now generated from a column "label" in all relevant cases to
+take advantage of excess-name-length rules, and checks for a peculiar collision
+against a column named the same as "tablename_colname" added
+- major overhaul to unit of work documentation, other documentation sections.
+- fixed attributes bug where if an object is committed, its lazy-loaded list got
+blown away if it hadnt been loaded
+- added unique_connection() method to engine, connection pool to return a
+connection that is not part of the thread-local context or any current
+transaction
+- added invalidate() function to pooled connection.  will remove the connection
+from the pool.  still need work for engines to auto-reconnect to a stale DB
+though.
+- added distinct() function to column elements so you can do
+func.count(mycol.distinct())
+- added "always_refresh" flag to Mapper, creates a mapper that will always
+refresh the attributes of objects it gets/selects from the DB, overwriting any
+changes made.
+
+0.1.4
+- create_engine() now uses genericized parameters; host/hostname,
+db/dbname/database, password/passwd, etc. for all engine connections. makes
+ engine URIs much more "universal"
+- added support for SELECT statements embedded into a column clause, using the
+flag "scalar=True"
+- another overhaul to EagerLoading when used in conjunction with mappers that
+inherit; improvements to eager loads figuring out their aliased queries
+correctly, also relations set up against a mapper with inherited mappers will
+create joins against the table that is specific to the mapper itself (i.e. and
+not any tables that are inherited/are further down the inheritance chain),
+this can be overridden by using custom primary/secondary joins.
+- added J.Ellis patch to mapper.py so that selectone() throws an exception
+if query returns more than one object row, selectfirst() to not throw the
+exception. also adds selectfirst_by (synonymous with get_by) and selectone_by
+- added onupdate parameter to Column, will exec SQL/python upon an update
+statement.Also adds "for_update=True" to all DefaultGenerator subclasses
+- added support for Oracle table reflection contributed by Andrija Zaric;
+still some bugs to work out regarding composite primary keys/dictionary selection
+- checked in an initial Firebird module, awaiting testing.
+- added sql.ClauseParameters dictionary object as the result for
+compiled.get_params(), does late-typeprocessing of bind parameters so
+that the original values are easier to access
+- more docs for indexes, column defaults, connection pooling, engine construction
+- overhaul to the construction of the types system. uses a simpler inheritance
+pattern so that any of the generic types can be easily subclassed, with no need
+for TypeDecorator.
+- added "convert_unicode=False" parameter to SQLEngine, will cause all String
+types to perform unicode encoding/decoding (makes Strings act like Unicodes)
+- added 'encoding="utf8"' parameter to engine.  the given encoding will be
+used for all encode/decode calls within Unicode types as well as Strings
+when convert_unicode=True.
+- improved support for mapping against UNIONs, added polymorph.py example
+to illustrate multi-class mapping against a UNION
+- fix to SQLite LIMIT/OFFSET syntax
+- fix to Oracle LIMIT syntax
+- added backref() function, allows backreferences to have keyword arguments
+that will be passed to the backref.
+- Sequences and ColumnDefault objects can do execute()/scalar() standalone
+- SQL functions (i.e. func.foo()) can do execute()/scalar() standalone
+- fix to SQL functions so that the ANSI-standard functions, i.e. current_timestamp
+etc., do not specify parenthesis.  all other functions do.
+- added settattr_clean and append_clean to SmartProperty, which set
+attributes without triggering a "dirty" event or any history. used as:
+myclass.prop1.setattr_clean(myobject, 'hi')
+- improved support to column defaults when used by mappers; mappers will pull
+pre-executed defaults from statement's executed bind parameters
+(pre-conversion) to populate them into a saved object's attributes; if any
+PassiveDefaults have fired off, will instead post-fetch the row from the DB to
+populate the object.
+- added 'get_session().invalidate(*obj)' method to objectstore, instances will
+refresh() themselves upon the next attribute access.
+- improvements to SQL func calls including an "engine" keyword argument so
+they can be execute()d or scalar()ed standalone, also added func accessor to
+SQLEngine
+- fix to MySQL4 custom table engines, i.e. TYPE instead of ENGINE
+- slightly enhanced logging, includes timestamps and a somewhat configurable
+formatting system, in lieu of a full-blown logging system
+- improvements to the ActiveMapper class from the TG gang, including
+many-to-many relationships
+- added Double and TinyInt support to mysql
+
+0.1.3
+- completed "post_update" feature, will add a second update statement before
+inserts and after deletes in order to reconcile a relationship without any
+dependencies being created; used when persisting two rows that are dependent
+on each other
+- completed mapper.using(session) function, localized per-object Session
+functionality; objects can be declared and manipulated as local to any
+user-defined Session
+- fix to Oracle "row_number over" clause with multiple tables
+- mapper.get() was not selecting multiple-keyed objects if the mapper's table was a join,
+such as in an inheritance relationship, this is fixed.
+- overhaul to sql/schema packages so that the sql package can run all on its own,
+producing selects, inserts, etc. without any engine dependencies.  builds upon
+new TableClause/ColumnClause lexical objects.  Schema's Table/Column objects
+are the "physical" subclasses of them.  simplifies schema/sql relationship,
+extensions (like proxyengine), and speeds overall performance by a large margin.
+removes the entire getattr() behavior that plagued 0.1.1.
+- refactoring of how the mapper "synchronizes" data between two objects into a
+separate module, works better with properties attached to a mapper that has an
+additional inheritance relationship to one of the related tables, also the same
+methodology used to synchronize parent/child objects now used by mapper to
+synchronize between inherited and inheriting mappers.
+- made objectstore "check for out-of-identitymap" more aggressive, will perform the
+check when object attributes are modified or the object is deleted
+- Index object fully implemented, can be constructed standalone, or via
+"index" and "unique" arguments on Columns.
+- added "convert_unicode" flag to SQLEngine, will treat all String/CHAR types
+as Unicode types, with raw-byte/utf-8 translation on the bind parameter and
+result set side.
+- postgres maintains a list of ANSI functions that must have no parenthesis so
+function calls with no arguments work consistently
+- tables can be created with no engine specified.  this will default their engine
+to a module-scoped "default engine" which is a ProxyEngine.  this engine can
+be connected via the function "global_connect".
+- added "refresh(*obj)" method to objectstore / Session to reload the attributes of
+any set of objects from the database unconditionally
+
+0.1.2
+- fixed a recursive call in schema that was somehow running 994 times then returning
+normally.  broke nothing, slowed down everything.  thanks to jpellerin for finding this.
+
+0.1.1
+- small fix to Function class so that expressions with a func.foo() use the type of the
+Function object (i.e. the left side) as the type of the boolean expression, not the
+other side which is more of a moving target (changeset 1020).
+- creating self-referring mappers with backrefs slightly easier (but still not that easy -
+changeset 1019)
+- fixes to one-to-one mappings (changeset 1015)
+- psycopg1 date/time issue with None fixed (changeset 1005)
+- two issues related to postgres, which doesnt want to give you the "lastrowid"
+since oids are deprecated:
+   * postgres database-side defaults that are on primary key cols *do* execute
+explicitly beforehand, even though thats not the idea of a PassiveDefault.  this is
+because sequences on columns get reflected as PassiveDefaults, but need to be explicitly
+executed on a primary key col so we know what we just inserted.
+   * if you did add a row that has a bunch of database-side defaults on it,
+and the PassiveDefault thing was working the old way, i.e. they just execute on
+the DB side, the "cant get the row back without an OID" exception that occurred
+also will not happen unless someone (usually the ORM) explicitly asks for it.
+- fixed a glitch with engine.execute_compiled where it was making a second
+ResultProxy that just got thrown away.
+- began to implement newer logic in object properities.  you can now say
+myclass.attr.property, which will give you the PropertyLoader corresponding to that
+attribute, i.e. myclass.mapper.props['attr']
+- eager loading has been internally overhauled to use aliases at all times.  more
+complicated chains of eager loads can now be created without any need for explicit
+"use aliases"-type instructions.  EagerLoader code is also much simpler now.
+- a new somewhat experimental flag "use_update" added to relations, indicates that
+this relationship should be handled by a second UPDATE statement, either after a
+primary INSERT or before a primary DELETE.  handles circular row dependencies.
+- added exceptions module, all raised exceptions (except for some
+KeyError/AttributeError exceptions) descend from these classes.
+- fix to date types with MySQL, returned timedelta converted to datetime.time
+- two-phase objectstore.commit operations (i.e. begin/commit) now return a
+transactional object (SessionTrans), to more clearly indicate transaction boundaries.
+- Index object with create/drop support added to schema
+- fix to postgres, where it will explicitly pre-execute a PassiveDefault on a table
+if it is a primary key column, pursuant to the ongoing "we cant get inserted rows
+back from postgres" issue
+- change to information_schema query that gets back postgres table defs, now
+uses explicit JOIN keyword, since one user had faster performance with 8.1
+- fix to engine.process_defaults so it works correctly with a table that has
+different column name/column keys (changset 982)
+- a column can only be attached to one table - this is now asserted
+- postgres time types descend from Time type
+- fix to alltests so that it runs types test (now named testtypes)
+- fix to Join object so that it correctly exports its foreign keys (cs 973)
+- creating relationships against mappers that use inheritance fixed (cs 973)
+
+0.1.0
+initial release
+
+