+-*- coding: utf-8; fill-column: 68 -*-
+Changes noted below are specific to version 0.8.
+For changes that are in both 0.7 and 0.8, see below
+ - SQLAlchemy 0.8 now targets Python 2.5 and
+ above. Python 2.4 is no longer supported.
+ - [removed] The "sqlalchemy.exceptions"
+ synonym for "sqlalchemy.exc" is removed
+ - [removed] The legacy "mutable" system of the
+ ORM, including the MutableType class as well
+ as the mutable=True flag on PickleType
+ and postgresql.ARRAY has been removed.
+ In-place mutations are detected by the ORM
+ using the sqlalchemy.ext.mutable extension,
+ introduced in 0.7. The removal of MutableType
+ and associated constructs removes a great
+ deal of complexity from SQLAlchemy's internals.
+ The approach performed poorly as it would incur
+ a scan of the full contents of the Session
+ when in use. [ticket:2442]
+ - [moved] The InstrumentationManager interface
+ and the entire related system of alternate
+ class implementation is now moved out
+ to sqlalchemy.ext.instrumentation. This is
+ a seldom used system that adds significant
+ complexity and overhead to the mechanics of
+ class instrumentation. The new architecture
+ allows it to remain unused until
+ InstrumentationManager is actually imported,
+ at which point it is bootstrapped into
+ - [feature] Major rewrite of relationship()
+ internals now allow join conditions which
+ include columns pointing to themselves
+ within composite foreign keys. A new
+ API for very specialized primaryjoin conditions
+ is added, allowing conditions based on
+ SQL functions, CAST, etc. to be handled
+ by placing the annotation functions
+ remote() and foreign() inline within the
+ expression when necessary. Previous recipes
+ using the semi-private _local_remote_pairs
+ approach can be upgraded to this new
+ approach. [ticket:1401]
+ - [bug] ORM will perform extra effort to determine
+ that an FK dependency between two tables is
+ not significant during flush if the tables
+ are related via joined inheritance and the FK
+ dependency is not part of the inherit_condition,
+ saves the user a use_alter directive.
+ - [feature] New standalone function with_polymorphic()
+ provides the functionality of query.with_polymorphic()
+ in a standalone form. It can be applied to any
+ entity within a query, including as the target
+ of a join in place of the "of_type()" modifier.
+ - [feature] The of_type() construct on attributes
+ now accepts aliased() class constructs as well
+ as with_polymorphic constructs, and works with
+ query.join(), any(), has(), and also
+ eager loaders subqueryload(), joinedload(),
+ [ticket:2438] [ticket:1106]
+ - [feature] Improvements to event listening for
+ mapped classes allows that unmapped classes
+ can be specified for instance- and mapper-events.
+ The established events will be automatically
+ set up on subclasses of that class when the
+ propagate=True flag is passed, and the
+ events will be set up for that class itself
+ if and when it is ultimately mapped.
+ - [bug] The instrumentation events class_instrument(),
+ class_uninstrument(), and attribute_instrument()
+ will now fire off only for descendant classes
+ of the class assigned to listen(). Previously,
+ an event listener would be assigned to listen
+ for all classes in all cases regardless of the
+ "target" argument passed. [ticket:2590]
+ - [bug] with_polymorphic() produces JOINs
+ in the correct order and with correct inheriting
+ tables in the case of sending multi-level
+ subclasses in an arbitrary order or with
+ intermediary classes missing. [ticket:1900]
+ - [feature] The "deferred declarative
+ reflection" system has been moved into the
+ declarative extension itself, using the
+ new DeferredReflection class. This
+ class is now tested with both single
+ and joined table inheritance use cases.
+ - [feature] Added new core function "inspect()",
+ which serves as a generic gateway to
+ introspection into mappers, objects,
+ others. The Mapper and InstanceState
+ objects have been enhanced with a public
+ API that allows inspection of mapped
+ attributes, including filters for column-bound
+ or relationship-bound properties, inspection
+ of current object state, history of
+ attributes, etc. [ticket:2208]
+ - [feature] Calling rollback() within a
+ session.begin_nested() will now only expire
+ those objects that had net changes within the
+ scope of that transaction, that is objects which
+ were dirty or were modified on a flush. This
+ allows the typical use case for begin_nested(),
+ that of altering a small subset of objects, to
+ leave in place the data from the larger enclosing
+ set of objects that weren't modified in
+ that sub-transaction. [ticket:2452]
+ - [feature] Added utility feature
+ supersedes relationship.load_on_pending.
+ Both features should be avoided, however.
+ - [feature] Added support for .info dictionary argument to
+ column_property(), relationship(), composite().
+ All MapperProperty classes have an auto-creating .info
+ dict available overall.
+ - [feature] Adding/removing None from a mapped collection
+ now generates attribute events. Previously, a None
+ append would be ignored in some cases. Related
+ - [feature] The presence of None in a mapped collection
+ now raises an error during flush. Previously,
+ None values in collections would be silently ignored.
+ - [feature] The Query.update() method is now
+ more lenient as to the table
+ being updated. Plain Table objects are better
+ supported now, and additional a joined-inheritance
+ subclass may be used with update(); the subclass
+ table will be the target of the update,
+ and if the parent table is referenced in the
+ WHERE clause, the compiler will call upon
+ UPDATE..FROM syntax as allowed by the dialect
+ to satisfy the WHERE clause. MySQL's multi-table
+ update feature is also supported if columns
+ are specified by object in the "values" dicitionary.
+ PG's DELETE..USING is also not available
+ - [feature] New session events after_transaction_create
+ and after_transaction_end
+ allows tracking of new SessionTransaction objects.
+ If the object is inspected, can be used to determine
+ when a session first becomes active and when
+ - [feature] The Query can now load entity/scalar-mixed
+ "tuple" rows that contain
+ types which aren't hashable, by setting the flag
+ "hashable=False" on the corresponding TypeEngine object
+ in use. Custom types that return unhashable types
+ (typically lists) can set this flag to False.
+ - [bug] Improvements to joined/subquery eager
+ loading dealing with chains of subclass entities
+ sharing a common base, with no specific "join depth"
+ provided. Will chain out to
+ each subclass mapper individually before detecting
+ a "cycle", rather than considering the base class
+ to be the source of the "cycle". [ticket:2481]
+ - [bug] The "passive" flag on Session.is_modified()
+ no longer has any effect. is_modified() in
+ all cases looks only at local in-memory
+ modified flags and will not emit any
+ SQL or invoke loader callables/initializers.
+ - [bug] The warning emitted when using
+ delete-orphan cascade with one-to-many
+ or many-to-many without single-parent=True
+ is now an error. The ORM
+ would fail to function subsequent to this
+ warning in any case. [ticket:2405]
+ - [bug] Lazy loads emitted within flush events
+ such as before_flush(), before_update(),
+ etc. will now function as they would
+ within non-event code, regarding consideration
+ of the PK/FK values used in the lazy-emitted
+ special flags would be established that
+ would cause lazy loads to load related items
+ based on the "previous" value of the
+ parent PK/FK values specifically when called
+ upon within a flush; the signal to load
+ in this way is now localized to where the
+ unit of work actually needs to load that
+ way. Note that the UOW does
+ sometimes load these collections before
+ the before_update() event is called,
+ so the usage of "passive_updates" or not
+ can affect whether or not a collection will
+ represent the "old" or "new" data, when
+ accessed within a flush event, based
+ on when the lazy load was emitted.
+ The change is backwards incompatible in
+ the exceedingly small chance that
+ user event code depended on the old
+ behavior. [ticket:2350]
+ - [feature] Query now "auto correlates" by
+ default in the same way as select() does.
+ Previously, a Query used as a subquery
+ in another would require the correlate()
+ method be called explicitly in order to
+ correlate a table on the inside to the
+ outside. As always, correlate(None)
+ disables correlation. [ticket:2179]
+ - [feature] The after_attach event is now
+ emitted after the object is established
+ in Session.new or Session.identity_map
+ upon Session.add(), Session.merge(),
+ etc., so that the object is represented
+ in these collections when the event
+ is called. Added before_attach
+ event to accommodate use cases that
+ need autoflush w pre-attached object.
+ - [feature] The Session will produce warnings
+ when unsupported methods are used inside the
+ "execute" portion of the flush. These are
+ the familiar methods add(), delete(), etc.
+ as well as collection and related-object
+ manipulations, as called within mapper-level
+ like after_insert(), after_update(), etc.
+ It's been prominently documented for a long
+ time that SQLAlchemy cannot guarantee
+ results when the Session is manipulated within
+ the execution of the flush plan,
+ however users are still doing it, so now
+ there's a warning. Maybe someday the Session
+ will be enhanced to support these operations
+ inside of the flush, but for now, results
+ - [bug] Continuing [ticket:2566] regarding extra
+ state post-flush due to event listeners;
+ any states that are marked as "dirty" from an
+ attribute perspective, usually via column-attribute
+ set events within after_insert(), after_update(),
+ etc., will get the "history" flag reset
+ in all cases, instead of only those instances
+ that were part of the flush. This has the effect
+ that this "dirty" state doesn't carry over
+ after the flush and won't result in UPDATE
+ statements. A warning is emitted to this
+ effect; the set_committed_state()
+ method can be used to assign attributes on objects
+ without producing history events. [ticket:2582]
+ - [feature] ORM entities can be passed
+ to the core select() construct as well
+ as to the select_from(),
+ correlate(), and correlate_except()
+ methods of select(), where they will be unwrapped
+ into selectables. [ticket:2245]
+ - [feature] Some support for auto-rendering of a
+ relationship join condition based on the mapped
+ attribute, with usage of core SQL constructs.
+ E.g. select([SomeClass]).where(SomeClass.somerelationship)
+ would render SELECT from "someclass" and use the
+ primaryjoin of "somerelationship" as the WHERE
+ clause. This changes the previous meaning
+ of "SomeClass.somerelationship" when used in a
+ core SQL context; previously, it would "resolve"
+ to the parent selectable, which wasn't generally
+ useful. Also works with query.filter().
+ Related to [ticket:2245].
+ - [feature] The registry of classes
+ in declarative_base() is now a
+ WeakValueDictionary. So subclasses of
+ "Base" that are dereferenced will be
+ garbage collected, *if they are not
+ referred to by any other mappers/superclass
+ mappers*. See the next note for this ticket.
+ - [feature] Conflicts between columns on
+ single-inheritance declarative subclasses,
+ with or without using a mixin, can be resolved
+ using a new @declared_attr usage described
+ in the documentation. [ticket:2472]
+ - [feature] declared_attr can now be used
+ on non-mixin classes, even though this is generally
+ only useful for single-inheritance subclass
+ column conflict resolution. [ticket:2472]
+ - [feature] declared_attr can now be used with
+ attributes that are not Column or MapperProperty;
+ including any user-defined value as well
+ as association proxy objects. [ticket:2517]
+ - [bug] Fixed a disconnect that slowly evolved
+ between a @declared_attr Column and a
+ directly-defined Column on a mixin. In both
+ cases, the Column will be applied to the
+ declared class' table, but not to that of a
+ joined inheritance subclass. Previously,
+ the directly-defined Column would be placed
+ on both the base and the sub table, which isn't
+ typically what's desired. [ticket:2565]
+ - [feature] *Very limited* support for
+ inheriting mappers to be GC'ed when the
+ class itself is deferenced. The mapper
+ must not have its own table (i.e.
+ single table inh only) without polymorphic
+ This allows for the use case of
+ creating a temporary subclass of a declarative
+ mapped class, with no table or mapping
+ directives of its own, to be garbage collected
+ when dereferenced by a unit test.
+ - [feature] Declarative now maintains a registry
+ of classes by string name as well as by full
+ module-qualified name. Multiple classes with the
+ same name can now be looked up based on a module-qualified
+ string within relationship(). Simple class name
+ lookups where more than one class shares the same
+ name now raises an informative error message.
+ - [feature] Can now provide class-bound attributes
+ that override columns which are of any
+ non-ORM type, not just descriptors.
+ - [feature] Added with_labels and
+ reduce_columns keyword arguments to
+ Query.subquery(), to provide two alternate
+ strategies for producing queries with uniquely-
+ named columns. [ticket:1729].
+ - [feature] A warning is emitted when a reference
+ to an instrumented collection is no longer
+ associated with the parent class due to
+ expiration/attribute refresh/collection
+ replacement, but an append
+ or remove operation is received on the
+ now-detached collection. [ticket:2476]
+ - [bug] Declarative can now propagate a column
+ declared on a single-table inheritance subclass
+ up to the parent class' table, when the parent
+ class is itself mapped to a join() or select()
+ statement, directly or via joined inheritance,
+ and not just a Table. [ticket:2549]
+ - [bug] An error is emitted when uselist=False
+ is combined with a "dynamic" loader.
+ This is a warning in 0.7.9.
+ - [removed] Deprecated identifiers removed:
+ * allow_null_pks mapper() argument
+ (use allow_partial_pks)
+ * _get_col_to_prop() mapper method
+ (use get_property_by_column())
+ * dont_load argument to Session.merge()
+ * sqlalchemy.orm.shard module
+ (use sqlalchemy.ext.horizontal_shard)
+ - [feature] Connection event listeners can
+ now be associated with individual
+ Connection objects, not just Engine
+ - [feature] The before_cursor_execute event
+ fires off for so-called "_cursor_execute"
+ events, which are usually special-case
+ executions of primary-key bound sequences
+ and default-generation SQL
+ phrases that invoke separately when RETURNING
+ is not used with INSERT. [ticket:2459]
+ - [feature] The libraries used by the test suite
+ have been moved around a bit so that they are
+ part of the SQLAlchemy install again. In addition,
+ a new suite of tests is present in the
+ new sqlalchemy.testing.suite package. This is
+ an under-development system that hopes to provide
+ a universal testing suite for external dialects.
+ Dialects which are maintained outside of SQLAlchemy
+ can use the new test fixture as the framework
+ for their own tests, and will get for free a
+ "compliance" suite of dialect-focused tests,
+ including an improved "requirements" system
+ where specific capabilities and features can
+ be enabled or disabled for testing.
+ - [bug] The Inspector.get_table_names()
+ order_by="foreign_key" feature now sorts
+ tables by dependee first, to be consistent
+ with util.sort_tables and metadata.sorted_tables.
+ - [bug] Fixed bug whereby if a database restart
+ affected multiple connections, each
+ connection would individually invoke a new
+ disposal of the pool, even though only
+ one disposal is needed. [ticket:2522]
+ - [feature] Added a new system
+ for registration of new dialects in-process
+ without using an entrypoint. See the
+ docs for "Registering New Dialects".
+ - [feature] The "required" flag is set to
+ True by default, if not passed explicitly,
+ on bindparam() if the "value" or "callable"
+ parameters are not passed.
+ This will cause statement execution to check
+ for the parameter being present in the final
+ collection of bound parameters, rather than
+ implicitly assigning None. [ticket:2556]
+ - [feature] Various API tweaks to the "dialect"
+ API to better support highly specialized
+ systems such as the Akiban database, including
+ more hooks to allow an execution context to
+ access type processors.
+ - [bug] The names of the columns on the
+ .c. attribute of a select().apply_labels()
+ is now based on <tablename>_<colkey> instead
+ of <tablename>_<colname>, for those columns
+ that have a distinctly named .key.
+ - [feature] Inspector.get_primary_keys() is
+ deprecated; use Inspector.get_pk_constraint().
+ Courtesy Diana Clarke. [ticket:2422]
+ - [bug] The autoload_replace flag on Table,
+ when False, will cause any reflected foreign key
+ constraints which refer to already-declared
+ columns to be skipped, assuming that the
+ in-Python declared column will take over
+ the task of specifying in-Python ForeignKey
+ or ForeignKeyConstraint declarations.
+ - [bug] The ResultProxy methods inserted_primary_key,
+ last_updated_params(), last_inserted_params(),
+ postfetch_cols(), prefetch_cols() all
+ assert that the given statement is a compiled
+ construct, and is an insert() or update()
+ statement as is appropriate, else
+ raise InvalidRequestError. [ticket:2498]
+ - [feature] New C extension module "utils" has
+ been added for additional function speedups
+ as we have time to implement.
+ - ResultProxy.last_inserted_ids is removed,
+ replaced by inserted_primary_key.
+ - [feature] Major rework of operator system
+ in Core, to allow redefinition of existing
+ operators as well as addition of new operators
+ at the type level. New types can be created
+ from existing ones which add or redefine
+ operations that are exported out to column
+ expressions, in a similar manner to how the
+ ORM has allowed comparator_factory. The new
+ architecture moves this capability into the
+ Core so that it is consistently usable in
+ all cases, propagating cleanly using existing
+ type propagation behavior. [ticket:2547]
+ - [feature] To complement [ticket:2547], types
+ can now provide "bind expressions" and
+ "column expressions" which allow compile-time
+ injection of SQL expressions into statements
+ on a per-column or per-bind level. This is
+ to suit the use case of a type which needs
+ to augment bind- and result- behavior at the
+ SQL level, as opposed to in the Python level.
+ Allows for schemes like transparent encryption/
+ decryption, usage of Postgis functions, etc.
+ - [feature] The Core oeprator system now includes
+ the `getitem` operator, i.e. the bracket
+ operator in Python. This is used at first
+ to provide index and slice behavior to the
+ Postgresql ARRAY type, and also provides a hook
+ for end-user definition of custom __getitem__
+ schemes which can be applied at the type
+ level as well as within ORM-level custom
+ operator schemes. `lshift` (<<)
+ and `rshift` (>>) are also supported as
+ Note that this change has the effect that
+ descriptor-based __getitem__ schemes used by
+ the ORM in conjunction with synonym() or other
+ "descriptor-wrapped" schemes will need
+ to start using a custom comparator in order
+ to maintain this behavior.
+ - [feature] Revised the rules used to determine
+ the operator precedence for the user-defined
+ operator, i.e. that granted using the ``op()``
+ method. Previously, the smallest precedence
+ was applied in all cases, now the default
+ precedence is zero, lower than all operators
+ except "comma" (such as, used in the argument
+ list of a ``func`` call) and "AS", and is
+ also customizable via the "precedence" argument
+ on the ``op()`` method. [ticket:2537]
+ - [feature] Added "collation" parameter to all
+ String types. When present, renders as
+ COLLATE <collation>. This to support the
+ COLLATE keyword now supported by several
+ databases including MySQL, SQLite, and Postgresql.
+ - [change] The Text() type renders the length
+ given to it, if a length was specified.
+ - [feature] Custom unary operators can now be
+ used by combining operators.custom_op() with
+ - [bug] A tweak to column precedence which moves the
+ "concat" and "match" operators to be the same as
+ that of "is", "like", and others; this helps with
+ parenthesization rendering when used in conjunction
+ with "IS". [ticket:2564]
+ - [feature] Enhanced GenericFunction and func.*
+ to allow for user-defined GenericFunction
+ subclasses to be available via the func.*
+ namespace automatically by classname,
+ optionally using a package name, as well
+ as with the ability to have the rendered
+ name different from the identified name
+ - [feature] The cast() and extract() constructs
+ will now be produced via the func.* accessor
+ as well, as users naturally try to access these
+ names from func.* they might as well do
+ what's expected, even though the returned
+ object is not a FunctionElement.
+ - [changed] Most classes in expression.sql
+ are no longer preceded with an underscore,
+ i.e. Label, SelectBase, Generative, CompareMixin.
+ _BindParamClause is also renamed to
+ BindParameter. The old underscore names for
+ these classes will remain available as synonyms
+ for the foreseeable future.
+ - [feature] The Inspector object can now be
+ acquired using the new inspect() service,
+ - [feature] The column_reflect event now
+ accepts the Inspector object as the first
+ argument, preceding "table". Code which
+ uses the 0.7 version of this very new
+ event will need modification to add the
+ "inspector" object as the first argument.
+ - [feature] The behavior of column targeting
+ in result sets is now case sensitive by
+ default. SQLAlchemy for many years would
+ run a case-insensitive conversion on these values,
+ probably to alleviate early case sensitivity
+ issues with dialects like Oracle and
+ Firebird. These issues have been more cleanly
+ solved in more modern versions so the performance
+ hit of calling lower() on identifiers is removed.
+ The case insensitive comparisons can be re-enabled
+ by setting "case_insensitive=False" on
+ create_engine(). [ticket:2423]
+ - [bug] Applying a column expression to a select
+ statement using a label with or without other
+ modifying constructs will no longer "target" that
+ expression to the underlying Column; this affects
+ ORM operations that rely upon Column targeting
+ in order to retrieve results. That is, a query
+ like query(User.id, User.id.label('foo')) will now
+ track the value of each "User.id" expression separately
+ instead of munging them together. It is not expected
+ that any users will be impacted by this; however,
+ a usage that uses select() in conjunction with
+ query.from_statement() and attempts to load fully
+ composed ORM entities may not function as expected
+ if the select() named Column objects with arbitrary
+ .label() names, as these will no longer target to
+ the Column objects mapped by that entity.
+ - [feature] The "unconsumed column names" warning emitted
+ when keys are present in insert.values() or update.values()
+ that aren't in the target table is now an exception.
+ - [feature] Added "MATCH" clause to ForeignKey,
+ ForeignKeyConstraint, courtesy Ryan Kelly.
+ - [feature] Added support for DELETE and UPDATE from
+ an alias of a table, which would assumedly
+ be related to itself elsewhere in the query,
+ courtesy Ryan Kelly. [ticket:2507]
+ - [feature] select() features a correlate_except()
+ method, auto correlates all selectables except those
+ - [feature] The prefix_with() method is now available
+ on each of select(), insert(), update(), delete(),
+ all with the same API, accepting multiple
+ prefix calls, as well as a "dialect name" so that
+ the prefix can be limited to one kind of dialect.
+ - [feature] Added reduce_columns() method
+ to select() construct, replaces columns inline
+ using the util.reduce_columns utility function
+ to remove equivalent columns. reduce_columns()
+ also adds "with_only_synonyms" to limit the
+ reduction just to those columns which have the same
+ name. The deprecated fold_equivalents() feature is
+ - [feature] Reworked the startswith(), endswith(),
+ contains() operators to do a better job with
+ negation (NOT LIKE), and also to assemble them
+ at compilation time so that their rendered SQL
+ can be altered, such as in the case for Firebird
+ STARTING WITH [ticket:2470]
+ - [feature] Added a hook to the system of rendering
+ CREATE TABLE that provides access to the render for each
+ Column individually, by constructing a @compiles
+ function against the new schema.CreateColumn
+ construct. [ticket:2463]
+ - [feature] "scalar" selects now have a WHERE method
+ to help with generative building. Also slight adjustment
+ regarding how SS "correlates" columns; the new methodology
+ no longer applies meaning to the underlying
+ Table column being selected. This improves
+ some fairly esoteric situations, and the logic
+ that was there didn't seem to have any purpose.
+ - [bug] Fixes to the interpretation of the
+ Column "default" parameter as a callable
+ to not pass ExecutionContext into a keyword
+ argument parameter. [ticket:2520]
+ - [bug] All of UniqueConstraint, ForeignKeyConstraint,
+ CheckConstraint, and PrimaryKeyConstraint will
+ attach themselves to their parent table automatically
+ when they refer to a Table-bound Column object directly
+ (i.e. not just string column name), and refer to
+ one and only one Table. Prior to 0.8 this behavior
+ occurred for UniqueConstraint and PrimaryKeyConstraint,
+ but not ForeignKeyConstraint or CheckConstraint.
+ - [bug] TypeDecorator now includes a generic repr()
+ that works in terms of the "impl" type by default.
+ This is a behavioral change for those TypeDecorator
+ classes that specify a custom __init__ method; those
+ types will need to re-define __repr__() if they need
+ __repr__() to provide a faithful constructor representation.
+ - [bug] column.label(None) now produces an
+ anonymous label, instead of returning the
+ column object itself, consistent with the behavior
+ of label(column, None). [ticket:2168]
+ - [feature] An explicit error is raised when
+ a ForeignKeyConstraint() that was
+ constructed to refer to multiple remote tables
+ is first used. [ticket:2455]
+ - [feature] the MS Access dialect has been
+ moved to its own project on Bitbucket,
+ taking advantage of the new SQLAlchemy
+ dialect compliance suite. The dialect is
+ still in very rough shape and probably not
+ ready for general use yet, however
+ it does have *extremely* rudimental
+ - [moved] The MaxDB dialect, which hasn't been
+ functional for several years, is
+ moved out to a pending bitbucket project,
+ - [feature] the SQLite date and time types
+ have been overhauled to support a more open
+ ended format for input and output, using
+ name based format strings and regexps. A
+ new argument "microseconds" also provides
+ the option to omit the "microseconds"
+ portion of timestamps. Thanks to
+ Nathan Wright for the work and tests on
+ - [feature] SQL Server dialect can be given
+ database-qualified schema names,
+ i.e. "schema='mydatabase.dbo'"; reflection
+ operations will detect this, split the schema
+ among the "." to get the owner separately,
+ and emit a "USE mydatabase" statement before
+ reflecting targets within the "dbo" owner;
+ the existing database returned from
+ DB_NAME() is then restored.
+ - [bug] removed legacy behavior whereby
+ a column comparison to a scalar SELECT via
+ == would coerce to an IN with the SQL server
+ dialect. This is implicit
+ behavior which fails in other scenarios
+ so is removed. Code which relies on this
+ needs to be modified to use column.in_(select)
+ explicitly. [ticket:2277]
+ - [feature] updated support for the mxodbc
+ driver; mxodbc 3.2.1 is recommended for full
+ - [feature] postgresql.ARRAY features an optional
+ "dimension" argument, will assign a specific
+ number of dimensions to the array which will
+ render in DDL as ARRAY..., also improves
+ performance of bind/result processing.
+ - [feature] postgresql.ARRAY now supports
+ indexing and slicing. The Python  operator
+ is available on all SQL expressions that are
+ of type ARRAY; integer or simple slices can be
+ passed. The slices can also be used on the
+ assignment side in the SET clause of an UPDATE
+ statement by passing them into Update.values();
+ see the docs for examples.
+ - [feature] Added new "array literal" construct
+ postgresql.array(). Basically a "tuple" that
+ renders as ARRAY[1,2,3].
+ - [feature] Added support for the Postgresql ONLY
+ keyword, which can appear corresponding to a
+ table in a SELECT, UPDATE, or DELETE statement.
+ The phrase is established using with_hint().
+ Courtesy Ryan Kelly [ticket:2506]
+ - [feature] The "ischema_names" dictionary of the
+ Postgresql dialect is "unofficially" customizable.
+ Meaning, new types such as PostGIS types can
+ be added into this dictionary, and the PG type
+ reflection code should be able to handle simple
+ types with variable numbers of arguments.
+ The functionality here is "unofficial" for
+ 1. this is not an "official" API. Ideally
+ an "official" API would allow custom type-handling
+ callables at the dialect or global level
+ 2. This is only implemented for the PG dialect,
+ in particular because PG has broad support
+ for custom types vs. other database backends.
+ A real API would be implemented at the
+ 3. The reflection code here is only tested against
+ simple types and probably has issues with more
+ patch courtesy Éric Lemoine.
+ - [feature] The "startswith()" operator renders
+ as "STARTING WITH", "~startswith()" renders
+ as "NOT STARTING WITH", using FB's more efficient
+ operator. [ticket:2470]
+ - [bug] CompileError is raised when VARCHAR with
+ no length is attempted to be emitted, same
+ way as MySQL. [ticket:2505]
+ - [bug] Firebird now uses strict "ansi bind rules"
+ so that bound parameters don't render in the
+ columns clause of a statement - they render
+ - [bug] Support for passing datetime as date when
+ using the DateTime type with Firebird; other
+ - [feature] An experimental dialect for the fdb
+ driver is added, but is untested as I cannot
+ get the fdb package to build. [ticket:2504]
+ - [bug] Dialect no longer emits expensive server
+ collations query, as well as server casing,
+ on first connect. These functions are still
+ available as semi-private. [ticket:2404]
+ - [feature] Added TIME type to mysql dialect,
+ accepts "fst" argument which is the new
+ "fractional seconds" specifier for recent
+ MySQL versions. The datatype will interpret
+ a microseconds portion received from the driver,
+ however note that at this time most/all MySQL
+ DBAPIs do not support returning this value.
+ - [bug] Quoting information is now passed along
+ from a Column with quote=True when generating
+ a same-named bound parameter to the bindparam()
+ object, as is the case in generated INSERT and UPDATE
+ statements, so that unknown reserved names can
+ be fully supported. [ticket:2437]
+ - [feature] The types of columns excluded from the
+ setinputsizes() set can be customized by sending
+ a list of string DBAPI type names to exclude,
+ using the exclude_setinputsizes dialect parameter.
+ This list was previously fixed. The list also
+ now defaults to STRING, UNICODE, removing
+ CLOB, NCLOB from the list. [ticket:2561]
+ - [bug] The CreateIndex construct in Oracle
+ will now schema-qualify the name of the index
+ to be that of the parent table. Previously this
+ name was omitted which apparently creates the
+ index in the default schema, rather than that
+ - [removed] The SQLSoup extension is removed from
+ SQLAlchemy, and is now an external project.
+ See http://pypi.python.org/pypi/sqlsoup .
+0.8 development begins during 0.7.7 development.
+and features listed below from version 0.7.7 on
+are also present in 0.8.
+ - [bug] Fixed Session accounting bug whereby replacing
+ a deleted object in the identity map with another
+ object of the same primary key would raise a
+ "conflicting state" error on rollback(),
+ if the replaced primary key were established either
+ via non-unitofwork-established INSERT statement
+ or by primary key switch of another instance.
+ - [bug] changed the list of cx_oracle types that are
+ excluded from the setinputsizes() step to only include
+ STRING and UNICODE; CLOB and NCLOB are removed. This
+ is to work around cx_oracle behavior which is broken
+ for the executemany() call. In 0.8, this same change
+ is applied however it is also configurable via the
+ exclude_setinputsizes argument. [ticket:2561]
+ - [feature] Added "raise_on_warnings" flag to OurSQL
+ - [feature] Added "read_timeout" flag to MySQLdb
+ - [bug] Fixed bug mostly local to new
+ AbstractConcreteBase helper where the "type"
+ attribute from the superclass would not
+ be overridden on the subclass to produce the
+ "reserved for base" error message, instead placing
+ a do-nothing attribute there. This was inconsistent
+ vs. using ConcreteBase as well as all the behavior
+ of classical concrete mappings, where the "type"
+ column from the polymorphic base would be explicitly
+ disabled on subclasses, unless overridden
+ - [bug] A warning is emitted when lazy='dynamic'
+ is combined with uselist=False. This is an
+ exception raise in 0.8.
+ - [bug] Fixed bug whereby user error in related-object
+ assignment could cause recursion overflow if the
+ assignment triggered a backref of the same name
+ as a bi-directional attribute on the incorrect
+ class to the same target. An informative
+ - [bug] Fixed bug where incorrect type information
+ would be passed when the ORM would bind the
+ "version" column, when using the "version" feature.
+ Tests courtesy Daniel Miller. [ticket:2539]
+ - [bug] Extra logic has been added to the "flush"
+ that occurs within Session.commit(), such that the
+ extra state added by an after_flush() or
+ after_flush_postexec() hook is also flushed in a
+ subsequent flush, before the "commit" completes.
+ Subsequent calls to flush() will continue until
+ the after_flush hooks stop adding new state.
+ An "overflow" counter of 100 is also in place,
+ in the event of a broken after_flush() hook
+ adding new content each time. [ticket:2566]
+ - [bug] Fixed the DropIndex construct to support
+ an Index associated with a Table in a remote
+ - [bug] Fixed bug in over() construct whereby
+ passing an empty list for either partition_by
+ or order_by, as opposed to None, would fail
+ Courtesy Gunnlaugur Þór Briem.
+ - [bug] Fixed CTE bug whereby positional
+ bound parameters present in the CTEs themselves
+ would corrupt the overall ordering of
+ bound parameters. This primarily
+ affected SQL Server as the platform with
+ positional binds + CTE support.
+ - [bug] Fixed more un-intuitivenesses in CTEs
+ which prevented referring to a CTE in a union
+ of itself without it being aliased.
+ CTEs now render uniquely
+ on name, rendering the outermost CTE of a given
+ name only - all other references are rendered
+ just as the name. This even includes other
+ CTE/SELECTs that refer to different versions
+ of the same CTE object, such as a SELECT
+ or a UNION ALL of that SELECT. We are
+ somewhat loosening the usual link between object
+ identity and lexical identity in this case.
+ A true name conflict between two unrelated
+ CTEs now raises an error.
+ - [bug] quoting is applied to the column names
+ inside the WITH RECURSIVE clause of a
+ common table expression according to the
+ quoting rules for the originating Column.
+ - [bug] Fixed regression introduced in 0.7.6
+ whereby the FROM list of a SELECT statement
+ could be incorrect in certain "clone+replace"
+ scenarios. [ticket:2518]
+ - [bug] Fixed bug whereby usage of a UNION
+ or similar inside of an embedded subquery
+ would interfere with result-column targeting,
+ in the case that a result-column had the same
+ ultimate name as a name inside the embedded
+ - [bug] Fixed a regression since 0.6 regarding
+ result-row targeting. It should be possible
+ to use a select() statement with string
+ based columns in it, that is
+ select(['id', 'name']).select_from('mytable'),
+ and have this statement be targetable by
+ Column objects with those names; this is the
+ works. At some point the specific case of
+ using select(['id']), which is equivalent to
+ select([literal_column('id')]), stopped working
+ here, so this has been re-instated and of
+ course tested. [ticket:2558]
+ - [bug] Added missing operators is_(), isnot()
+ to the ColumnOperators base, so that these long-available
+ operators are present as methods like all
+ the other operators. [ticket:2544]
+ - [bug] When the primary key column of a Table
+ is replaced, such as via extend_existing,
+ the "auto increment" column used by insert()
+ constructs is reset. Previously it would
+ remain referring to the previous primary
+ key column. [ticket:2525]
+ - [bug] Fixed bug whereby
+ a disconnect detect + dispose that occurs
+ when the QueuePool has threads waiting
+ for connections would leave those
+ threads waiting for the duration of
+ the timeout on the old pool (or indefinitely
+ if timeout was disabled). The fix
+ now notifies those waiters with a special
+ exception case and has them move onto
+ the new pool. [ticket:2522]
+ - [feature] Dramatic improvement in memory
+ usage of the event system; instance-level
+ collections are no longer created for a
+ particular type of event until
+ instance-level listeners are established
+ for that event. [ticket:2516]
+ - [bug] Added gaerdbms import to mysql/__init__.py,
+ the absense of which was preventing the new
+ GAE dialect from being loaded. [ticket:2529]
+ - [bug] Fixed cextension bug whereby the
+ "ambiguous column error" would fail to
+ function properly if the given index were
+ a Column object and not a string.
+ Note there are still some column-targeting
+ issues here which are fixed in 0.8.
+ - [bug] Fixed the repr() of Enum to include
+ the "name" and "native_enum" flags. Helps
+ - [bug] Adjusted a very old bugfix which attempted
+ to work around a SQLite issue that itself was
+ "fixed" as of sqlite 3.6.14, regarding quotes
+ surrounding a table name when using
+ the "foreign_key_list" pragma. The fix has been
+ adjusted to not interfere with quotes that
+ are *actually in the name* of a column or table,
+ to as much a degree as possible; sqlite still
+ doesn't return the correct result for foreign_key_list()
+ if the target table actually has quotes surrounding
+ its name, as *part* of its name (i.e. """mytable""").
+ - [bug] Adjusted column default reflection code to
+ convert non-string values to string, to accommodate
+ old SQLite versions that don't deliver
+ default info as a string. [ticket:2265]
+ - [feature] Added support for the localtimestamp()
+ SQL function implemented in SQLite, courtesy
+ - [bug] Columns in reflected primary key constraint
+ are now returned in the order in which the constraint
+ itself defines them, rather than how the table
+ orders them. Courtesy Gunnlaugur Þór Briem.
+ - [bug] Added 'terminating connection' to the list
+ of messages we use to detect a disconnect with PG, which
+ appears to be present in some versions when the server
+ is restarted. [ticket:2570]
+ - [bug] Updated mysqlconnector interface to use
+ updated "client flag" and "charset" APIs,
+ courtesy David McNelis.
+ - [bug] Fixed compiler bug whereby using a correlated
+ subquery within an ORDER BY would fail to render correctly
+ if the stament also used LIMIT/OFFSET, due to mis-rendering
+ within the ROW_NUMBER() OVER clause. Fix courtesy
+ - [bug] Fixed compiler bug whereby a given
+ select() would be modified if it had an "offset"
+ attribute, causing the construct to not compile
+ correctly a second time. [ticket:2545]
+ - [bug] Fixed bug where reflection of primary key constraint
+ would double up columns if the same constraint/table
+ existed in multiple schemas.
+ - [bug] Fixed bug whereby subqueryload() from
+ a polymorphic mapping to a target would incur
+ a new invocation of the query for each
+ distinct class encountered in the polymorphic
+ - [bug] Fixed bug in declarative
+ whereby the precedence of columns
+ in a joined-table, composite
+ column (typically for id) would fail to
+ be correct if the columns contained
+ names distinct from their attribute
+ names. This would cause things like
+ primaryjoin conditions made against the
+ entity attributes to be incorrect. Related
+ to [ticket:1892] as this was supposed
+ to be part of that, this is [ticket:2491].
+ - [feature] The 'objects' argument to
+ flush() is no longer deprecated, as some
+ valid use cases have been identified.
+ - [bug] Fixed identity_key() function which
+ was not accepting a scalar argument
+ for the identity. [ticket:2508].
+ - [bug] Fixed bug whereby populate_existing
+ option would not propagate to subquery
+ eager loaders. [ticket:2497].
+ - [bug] added BIGINT to types.__all__,
+ BIGINT, BINARY, VARBINARY to sqlalchemy
+ module namespace, plus test to ensure
+ this breakage doesn't occur again.
+ - [bug] Repaired common table expression
+ rendering to function correctly when the
+ SELECT statement contains UNION or other
+ compound expressions, courtesy btbuilder.
+ - [bug] Fixed bug whereby append_column()
+ wouldn't function correctly on a cloned
+ select() construct, courtesy
+ Gunnlaugur Þór Briem. [ticket:2482]
+ - [bug] Fixed memory leak in C version of
+ result proxy whereby DBAPIs which don't deliver
+ pure Python tuples for result rows would
+ fail to decrement refcounts correctly.
+ The most prominently affected DBAPI
+ is pyodbc. [ticket:2489]
+ - [bug] Fixed bug affecting Py3K whereby
+ string positional parameters passed to
+ engine/connection execute() would fail to be
+ interpreted correctly, due to __iter__
+ being present on Py3K string.
+ - [bug] removed unnecessary table clause when
+ reflecting enums, [ticket:2510]. Courtesy
+ - [bug] Added ROWID to oracle.*, [ticket:2483]
+ - [feature] Added a new dialect for Google App
+ Engine. Courtesy Richie Foreman. [ticket:2484]
+ - [bug] Fixed issue in unit of work
+ whereby setting a non-None self-referential
+ many-to-one relationship to None
+ would fail to persist the change if the
+ former value was not already loaded.
+ - [feature] Added prefix_with() method
+ to Query, calls upon select().prefix_with()
+ to allow placement of MySQL SELECT
+ directives in statements. Courtesy
+ Diana Clarke [ticket:2443]
+ - [bug] Fixed bug in 0.7.6 introduced by
+ [ticket:2409] whereby column_mapped_collection
+ used against columns that were mapped as
+ joins or other indirect selectables
+ would fail to function.
+ - [feature] Added new flag to @validates
+ include_removes. When True, collection
+ remove and attribute del events
+ will also be sent to the validation function,
+ which accepts an additional argument
+ "is_remove" when this flag is used.
+ - [bug] Fixed bug whereby polymorphic_on
+ column that's not otherwise mapped on the
+ class would be incorrectly included
+ in a merge() operation, raising an error.
+ - [bug] Fixed bug in expression annotation
+ mechanics which could lead to incorrect
+ rendering of SELECT statements with aliases
+ and joins, particularly when using
+ column_property(). [ticket:2453]
+ - [bug] Fixed bug which would prevent
+ OrderingList from being pickleable
+ [ticket:2454]. Courtesy Jeff Dairiki
+ - [bug] Fixed bug in relationship comparisons
+ whereby calling unimplemented methods like
+ SomeClass.somerelationship.like() would
+ produce a recursion overflow, instead
+ of NotImplementedError.
+ - [bug] Removed warning when Index is created
+ with no columns; while this might not be what
+ the user intended, it is a valid use case
+ as an Index could be a placeholder for just an
+ index of a certain name.
+ - [feature] Added new connection event
+ dbapi_error(). Is called for all DBAPI-level
+ errors passing the original DBAPI exception
+ before SQLAlchemy modifies the state
+ - [bug] If conn.begin() fails when calling
+ "with engine.begin()", the newly acquired
+ Connection is closed explicitly before
+ propagating the exception onward normally.
+ - [bug] Add BINARY, VARBINARY to types.__all__,
+ - [feature] Added interim create_engine flag
+ supports_unicode_binds to PyODBC dialect,
+ to force whether or not the dialect
+ passes Python unicode literals to PyODBC
+ - [bug] Repaired the use_scope_identity
+ create_engine() flag when using the pyodbc
+ dialect. Previously this flag would be
+ ignored if set to False. When set to False,
+ you'll get "SELECT @@identity" after each
+ INSERT to get at the last inserted ID,
+ for those tables which have "implicit_returning"
+ - [bug] UPDATE..FROM syntax with SQL Server
+ requires that the updated table be present
+ in the FROM clause when an alias of that
+ table is also present in the FROM clause.
+ The updated table is now always present
+ in the FROM, when FROM is present
+ in the first place. Courtesy sayap.
+ - [feature] Added new for_update/with_lockmode()
+ options for Postgresql: for_update="read"/
+ These emit "FOR SHARE" and "FOR SHARE NOWAIT",
+ respectively. Courtesy Diana Clarke
+ - [bug] removed unnecessary table clause
+ when reflecting domains, [ticket:2473]
+ - [bug] Fixed bug whereby column name inside
+ of "KEY" clause for autoincrement composite
+ column with InnoDB would double quote a
+ name that's a reserved word. Courtesy Jeff
+ - [bug] Fixed bug whereby get_view_names() for
+ "information_schema" schema would fail
+ to retrieve views marked as "SYSTEM VIEW".
+ courtesy Matthew Turland.
+ - [bug] Fixed bug whereby if cast() is used
+ on a SQL expression whose type is not supported
+ by cast() and therefore CAST isn't rendered by
+ the dialect, the order of evaluation could change
+ if the casted expression required that it be
+ grouped; grouping is now applied to those
+ expressions. [ticket:2467]
+ - [feature] Added SQLite execution option
+ "sqlite_raw_colnames=True", will bypass
+ attempts to remove "." from column names
+ returned by SQLite cursor.description.
+ - [bug] Fixed event registration bug
+ which would primarily show up as
+ events not being registered with
+ sessionmaker() instances created
+ after the event was associated
+ with the Session class. [ticket:2424]
+ - [bug] Fixed bug whereby a primaryjoin
+ condition with a "literal" in it would
+ raise an error on compile with certain
+ kinds of deeply nested expressions
+ which also needed to render the same
+ bound parameter name more than once.
+ - [feature] Added "no_autoflush" context
+ manager to Session, used with with:
+ will temporarily disable autoflush.
+ - [feature] Added cte() method to Query,
+ invokes common table expression support
+ from the Core (see below). [ticket:1859]
+ - [bug] Removed the check for number of
+ rows affected when doing a multi-delete
+ against mapped objects. If an ON DELETE
+ CASCADE exists between two rows, we can't
+ get an accurate rowcount from the DBAPI;
+ this particular count is not supported
+ on most DBAPIs in any case, MySQLdb
+ is the notable case where it is.
+ - [bug] Fixed bug whereby objects using
+ attribute_mapped_collection or
+ column_mapped_collection could not be
+ - [bug] Fixed bug whereby MappedCollection
+ would not get the appropriate collection
+ instrumentation if it were only used
+ in a custom subclass that used
+ - [bug] Fixed bug whereby SQL adaption mechanics
+ would fail in a very nested scenario involving
+ joined-inheritance, joinedload(), limit(), and a
+ derived function in the columns clause.
+ - [bug] Fixed the repr() for CascadeOptions to
+ include refresh-expire. Also reworked
+ CascadeOptions to be a <frozenset>.
+ - [feature] Added the ability to query for
+ Table-bound column names when using
+ - [bug] Improved the "declarative reflection"
+ example to support single-table inheritance,
+ multiple calls to prepare(), tables that
+ are present in alternate schemas,
+ establishing only a subset of classes
+ - [bug] Scaled back the test applied within
+ flush() to check for UPDATE against partially
+ NULL PK within one table to only actually
+ happen if there's really an UPDATE to occur.
+ - [bug] Fixed bug whereby if a method name
+ conflicted with a column name, a
+ TypeError would be raised when the mapper
+ tried to inspect the __get__() method
+ on the method object. [ticket:2352]
+ - [bug] Fixed memory leak in core which would
+ occur when C extensions were used with
+ particular types of result fetches,
+ in particular when orm query.count()
+ were called. [ticket:2427]
+ - [bug] Fixed issue whereby attribute-based
+ column access on a row would raise
+ AttributeError with non-C version,
+ NoSuchColumnError with C version. Now
+ raises AttributeError in both cases.
+ - [feature] Added support for SQL standard
+ common table expressions (CTE), allowing
+ SELECT objects as the CTE source (DML
+ not yet supported). This is invoked via
+ the cte() method on any select() construct.
+ - [bug] Added support for using the .key
+ of a Column as a string identifier in a
+ result set row. The .key is currently
+ listed as an "alternate" name for a column,
+ and is superseded by the name of a column
+ which has that key value as its regular name.
+ For the next major release
+ of SQLAlchemy we may reverse this precedence
+ so that .key takes precedence, but this
+ is not decided on yet. [ticket:2392]
+ - [bug] A warning is emitted when a not-present
+ column is stated in the values() clause
+ of an insert() or update() construct.
+ Will move to an exception in 0.8.
+ - [bug] A significant change to how labeling
+ is applied to columns in SELECT statements
+ allows "truncated" labels, that is label names
+ that are generated in Python which exceed
+ the maximum identifier length (note this is
+ configurable via label_length on create_engine()),
+ to be properly referenced when rendered inside
+ of a subquery, as well as to be present
+ in a result set row using their original
+ in-Python names. [ticket:2396]
+ - [bug] Fixed bug in new "autoload_replace" flag
+ which would fail to preserve the primary
+ key constraint of the reflected table.
+ - [bug] Index will raise when arguments passed
+ cannot be interpreted as columns or expressions.
+ Will warn when Index is created
+ with no columns at all. [ticket:2380]
+ - [feature] Added "no_parameters=True" execution
+ option for connections. If no parameters
+ are present, will pass the statement
+ as cursor.execute(statement), thereby invoking
+ the DBAPIs behavior when no parameter collection
+ is present; for psycopg2 and mysql-python, this
+ means not interpreting % signs in the string.
+ This only occurs with this option, and not
+ just if the param list is blank, as otherwise
+ this would produce inconsistent behavior
+ of SQL expressions that normally escape percent
+ signs (and while compiling, can't know ahead of
+ time if parameters will be present in
+ some cases). [ticket:2407]
+ - [bug] Added execution_options() call to
+ MockConnection (i.e., that used with
+ strategy="mock") which acts as a pass through
+ - [feature] Added pool_reset_on_return argument
+ to create_engine, allows control over
+ "connection return" behavior. Also added
+ new arguments 'rollback', 'commit', None
+ to pool.reset_on_return to allow more control
+ over connection return activity. [ticket:2378]
+ - [feature] Added some decent context managers
+ with engine.begin() as conn:
+ <work with conn in a transaction>
+ with engine.connect() as conn:
+ Both close out the connection when done,
+ commit or rollback transaction with errors
+ - [bug] Fixed bug in C extensions whereby
+ string format would not be applied to a
+ Numeric value returned as integer; this
+ affected primarily SQLite which does
+ not maintain numeric scale settings.
+ - [feature] Added support for MSSQL INSERT,
+ UPDATE, and DELETE table hints, using
+ new with_hint() method on UpdateBase.
+ - [feature] Added support for MySQL index and
+ primary key constraint types
+ (i.e. USING) via new mysql_using parameter
+ to Index and PrimaryKeyConstraint,
+ courtesy Diana Clarke. [ticket:2386]
+ - [feature] Added support for the "isolation_level"
+ parameter to all MySQL dialects. Thanks
+ to mu_mind for the patch here. [ticket:2394]
+ - [feature] Added a new create_engine() flag
+ coerce_to_decimal=False, disables the precision
+ numeric handling which can add lots of overhead
+ by converting all numeric values to
+ - [bug] Added missing compilation support for
+ - [bug] Added 'LEVEL' to the list of reserved
+ words for Oracle. [ticket:2435]
+ - [bug] Altered _params_from_query() function
+ in Beaker example to pull bindparams from the
+ fully compiled statement, as a quick means
+ to get everything including subqueries in the
+0.7.5 (January 28, 2012)
+ - [bug] Fixed issue where modified session state
+ established after a failed flush would be committed
+ as part of the subsequent transaction that
+ begins automatically after manual call
+ to rollback(). The state of the session is
+ checked within rollback(), and if new state
+ is present, a warning is emitted and
+ restore_snapshot() is called a second time,
+ discarding those changes. [ticket:2389]
+ - [bug] Fixed regression from 0.7.4 whereby
+ using an already instrumented column from a
+ superclass as "polymorphic_on" failed to resolve
+ the underlying Column. [ticket:2345]
+ - [bug] Raise an exception if xyzload_all() is
+ used inappropriately with two non-connected
+ relationships. [ticket:2370]
+ - [feature] Added "class_registry" argument to
+ declarative_base(). Allows two or more declarative
+ bases to share the same registry of class names.
+ - [feature] query.filter() accepts multiple
+ criteria which will join via AND, i.e.
+ query.filter(x==y, z>q, ...)
+ - [feature] Added new capability to relationship
+ loader options to allow "default" loader strategies.
+ Pass '*' to any of joinedload(), lazyload(),
+ subqueryload(), or noload() and that becomes the
+ loader strategy used for all relationships,
+ except for those explicitly stated in the
+ Query. Thanks to up-and-coming contributor
+ Kent Bower for an exhaustive and well
+ written test suite ! [ticket:2351]
+ - [bug] Fixed bug whereby event.listen(SomeClass)
+ forced an entirely unnecessary compile of the
+ mapper, making events very hard to set up
+ at module import time (nobody noticed this ??)
+ - [bug] Fixed bug whereby hybrid_property didn't
+ work as a kw arg in any(), has().
+ - Fixed regression from 0.6 whereby if
+ "load_on_pending" relationship() flag were used
+ where a non-"get()" lazy clause needed to be
+ emitted on a pending object, it would fail
+ - [bug] ensure pickleability of all ORM exceptions
+ for multiprocessing compatibility. [ticket:2371]
+ - [bug] implemented standard "can't set attribute" /
+ "can't delete attribute" AttributeError when
+ setattr/delattr used on a hybrid that doesn't
+ define fset or fdel. [ticket:2353]
+ - [bug] Fixed bug where unpickled object didn't
+ have enough of its state set up to work
+ correctly within the unpickle() event established
+ by the mutable object extension, if the object
+ needed ORM attribute access within
+ __eq__() or similar. [ticket:2362]
+ - [bug] Fixed bug where "merge" cascade could
+ mis-interpret an unloaded attribute, if the
+ load_on_pending flag were used with
+ relationship(). Thanks to Kent Bower
+ for tests. [ticket:2374]
+ - [feature] New declarative reflection example
+ added, illustrates how best to mix table reflection
+ with declarative as well as uses some new features
+ - [feature] New reflection feature "autoload_replace";
+ when set to False on Table, the Table can be autoloaded
+ without existing columns being replaced. Allows
+ more flexible chains of Table construction/reflection
+ to be constructed, including that it helps with
+ combining Declarative with table reflection.
+ See the new example on the wiki. [ticket:2356]
+ - [bug] Improved the API for add_column() such that
+ if the same column is added to its own table,
+ an error is not raised and the constraints
+ don't get doubled up. Also helps with some
+ reflection/declarative patterns. [ticket:2356]
+ - [feature] Added "false()" and "true()" expression
+ constructs to sqlalchemy.sql namespace, though
+ not part of __all__ as of yet.
+ - [feature] Dialect-specific compilers now raise
+ CompileException for all type/statement compilation
+ issues, instead of InvalidRequestError or ArgumentError.
+ The DDL for CREATE TABLE will re-raise
+ CompileExceptions to include table/column information
+ for the problematic column. [ticket:2361]
+ - [bug] Fixed issue where the "required" exception
+ would not be raised for bindparam() with required=True,
+ if the statement were given no parameters at all.
+ - [bug] Added __reduce__ to StatementError,
+ DBAPIError, column errors so that exceptions
+ are pickleable, as when using multiprocessing.
+ all DBAPIs support this yet, such as
+ psycopg2. [ticket:2371]
+ - [bug] Improved error messages when a non-string
+ or invalid string is passed to any of the
+ date/time processors used by SQLite, including
+ C and Python versions. [ticket:2382]
+ - [bug] Fixed bug whereby a table-bound Column
+ object named "<a>_<b>" which matched a column
+ labeled as "<tablename>_<colname>" could match
+ inappropriately when targeting in a result
+ - [bug] Fixed bug in "mock" strategy whereby
+ correct DDL visit method wasn't called, resulting
+ in "CREATE/DROP SEQUENCE" statements being
+ duplicated [ticket:2384]
+ - [bug] the "name" of an FK constraint in SQLite
+ is reflected as "None", not "0" or other
+ integer value [ticket:2364].
+ SQLite does not appear to support constraint
+ - [bug] sql.false() and sql.true() compile to
+ 0 and 1, respectively in sqlite [ticket:2368]
+ - [bug] removed an erroneous "raise" in the
+ SQLite dialect when getting table names
+ and view names, where logic is in place
+ to fall back to an older version of
+ SQLite that doesn't have the
+ "sqlite_temp_master" table.
+ - [bug] fixed regexp that filters out warnings
+ for non-reflected "PARTITION" directives,
+ thanks to George Reilly [ticket:2376]
+ - [bug] Adjusted the regexp used in the
+ mssql.TIME type to ensure only six digits
+ are received for the "microseconds" portion
+ of the value, which is expected by
+ Python's datetime.time(). Note that
+ support for sending microseconds doesn't
+ seem to be possible yet with pyodbc
+ at least. [ticket:2340]
+ - [bug] Dropped the "30 char" limit on pymssql,
+ based on reports that it's doing things
+ better these days. pymssql hasn't been
+ well tested and as the DBAPI is in flux
+ it's still not clear what the status
+ is on this driver and how SQLAlchemy's
+ implementation should adapt. [ticket:2347]
+ - [bug] Added ORA-03135 to the never ending
+ list of oracle "connection lost" errors
+ - [bug] Changed LRUCache, used by the mapper
+ to cache INSERT/UPDATE/DELETE statements,
+ to use an incrementing counter instead
+ of a timestamp to track entries, for greater
+ reliability versus using time.time(), which
+ can cause test failures on some platforms.
+ - [bug] Added a boolean check for the "finalize"
+ function within the pool connection proxy's
+ weakref callback before calling it, so that a
+ warning isn't emitted that this function is None
+ when the application is exiting and gc has
+ removed the function from the module before the
+ weakref callback was invoked. [ticket:2383]
+ - [bug] Fixed inappropriate usage of util.py3k
+ flag and renamed it to util.py3k_warning, since
+ this flag is intended to detect the -3 flag
+ series of import restrictions only.
+ - [feature] Simplified the versioning example
+ a bit to use a declarative mixin as well
+ as an event listener, instead of a metaclass +
+ SessionExtension. [ticket:2313]
+ - [bug] Fixed large_collection.py to close the
+ session before dropping tables. [ticket:2346]
+0.7.4 (December 9, 2011)
+ - [bug] Fixed backref behavior when "popping" the
+ value off of a many-to-one in response to
+ a removal from a stale one-to-many - the operation
+ is skipped, since the many-to-one has since
+ been updated. [ticket:2315]
+ - [bug] After some years of not doing this, added
+ more granularity to the "is X a parent of Y"
+ functionality, which is used when determining
+ if the FK on "Y" needs to be "nulled out" as well
+ as if "Y" should be deleted with delete-orphan
+ cascade. The test now takes into account the
+ Python identity of the parent as well its identity
+ key, to see if the last known parent of Y is
+ definitely X. If a decision
+ can't be made, a StaleDataError is raised. The
+ conditions where this error is raised are fairly
+ rare, requiring that the previous parent was
+ garbage collected, and previously
+ could very well inappropriately update/delete
+ a record that's since moved onto a new parent,
+ though there may be some cases where
+ "silent success" occurred previously that will now
+ raise in the face of ambiguity.
+ Expiring "Y" resets the "parent" tracker, meaning
+ X.remove(Y) could then end up deleting Y even
+ if X is stale, but this is the same behavior
+ as before; it's advised to expire X also in that
+ - [bug] fixed inappropriate evaluation of user-mapped
+ object in a boolean context within query.get()
+ [ticket:2310]. Also in 0.6.9.
+ - [bug] Added missing comma to PASSIVE_RETURN_NEVER_SET
+ - [bug] Cls.column.collate("some collation") now
+ works. [ticket:1776] Also in 0.6.9
+ - [bug] the value of a composite attribute is now
+ expired after an insert or update operation, instead
+ of regenerated in place. This ensures that a
+ column value which is expired within a flush
+ will be loaded first, before the composite
+ is regenerated using that value. [ticket:2309]
+ - [bug] The fix in [ticket:2309] also emits the
+ "refresh" event when the composite value is
+ loaded on access, even if all column
+ values were already present, as is appropriate.
+ This fixes the "mutable" extension which relies
+ upon the "load" event to ensure the _parents
+ dictionary is up to date, fixes [ticket:2308].
+ Thanks to Scott Torborg for the test case here.
+ - [bug] Fixed bug whereby a subclass of a subclass
+ using concrete inheritance in conjunction with
+ the new ConcreteBase or AbstractConcreteBase
+ would fail to apply the subclasses deeper than
+ one level to the "polymorphic loader" of each
+ - [bug] Fixed bug whereby a subclass of a subclass
+ using the new AbstractConcreteBase would fail
+ to acquire the correct "base_mapper" attribute
+ when the "base" mapper was generated, thereby
+ causing failures later on. [ticket:2312]
+ - [bug] Fixed bug whereby column_property() created
+ against ORM-level column could be treated as
+ a distinct entity when producing certain
+ kinds of joined-inh joins. [ticket:2316]
+ - [bug] Fixed the error formatting raised when
+ a tuple is inadvertently passed to session.query()
+ [ticket:2297]. Also in 0.6.9.
+ - [bug] Calls to query.join() to a single-table
+ inheritance subclass are now tracked, and
+ are used to eliminate the additional WHERE..
+ IN criterion normally tacked on with single
+ table inheritance, since the join should
+ accommodate it. This allows OUTER JOIN
+ to a single table subclass to produce
+ the correct results, and overall will produce
+ fewer WHERE criterion when dealing with
+ single table inheritance joins.
+ - [bug] __table_args__ can now be passed as
+ an empty tuple as well as an empty dict.
+ [ticket:2339]. Thanks to Fayaz Yusuf Khan
+ - [bug] Updated warning message when setting
+ delete-orphan without delete to no longer
+ refer to 0.6, as we never got around to
+ upgrading this to an exception. Ideally
+ this might be better as an exception but
+ it's not critical either way. [ticket:2325]
+ - [feature] polymorphic_on now accepts many
+ - standalone expressions that aren't
+ - column_property() objects
+ - string names of any column_property()
+ or attribute name of a mapped Column
+ The docs include an example using
+ the case() construct, which is likely to be
+ a common constructed used here.
+ [ticket:2345] and part of [ticket:2238]
+ Standalone expressions in polymorphic_on
+ propagate to single-table inheritance
+ subclasses so that they are used in the
+ WHERE /JOIN clause to limit rows to that
+ subclass as is the usual behavior.
+ - [feature] IdentitySet supports the - operator
+ as the same as difference(), handy when dealing
+ with Session.dirty etc. [ticket:2301]
+ - [feature] Added new value for Column autoincrement
+ called "ignore_fk", can be used to force autoincrement
+ on a column that's still part of a ForeignKeyConstraint.
+ New example in the relationship docs illustrates
+ - [bug] Fixed bug in get_history() when referring
+ to a composite attribute that has no value;
+ added coverage for get_history() regarding
+ composites which is otherwise just a userland
+ - [bug] related to [ticket:2316], made some
+ adjustments to the change from [ticket:2261]
+ regarding the "from" list on a select(). The
+ _froms collection is no longer memoized, as this
+ simplifies various use cases and removes the
+ need for a "warning" if a column is attached
+ to a table after it was already used in an
+ expression - the select() construct will now
+ always produce the correct expression.
+ There's probably no real-world
+ performance hit here; select() objects are
+ almost always made ad-hoc, and systems that
+ wish to optimize the re-use of a select()
+ would be using the "compiled_cache" feature.
+ A hit which would occur when calling select.bind
+ has been reduced, but the vast majority
+ of users shouldn't be using "bound metadata"
+ - [feature] The update() construct can now accommodate
+ multiple tables in the WHERE clause, which will
+ render an "UPDATE..FROM" construct, recognized by
+ Postgresql and MSSQL. When compiled on MySQL,
+ will instead generate "UPDATE t1, t2, ..". MySQL
+ additionally can render against multiple tables in the
+ SET clause, if Column objects are used as keys
+ in the "values" parameter or generative method.
+ [ticket:2166] [ticket:1944]
+ - [feature] Added accessor to types called "python_type",
+ returns the rudimentary Python type object
+ for a particular TypeEngine instance, if known,
+ else raises NotImplementedError. [ticket:77]
+ - [bug] further tweak to the fix from [ticket:2261],
+ so that generative methods work a bit better
+ off of cloned (this is almost a non-use case though).
+ In particular this allows with_only_columns()
+ to behave more consistently. Added additional
+ documentation to with_only_columns() to clarify
+ expected behavior, which changed as a result
+ of [ticket:2261]. [ticket:2319]
+ - [bug] Fixed bug whereby transaction.rollback()
+ would throw an error on an invalidated
+ connection if the transaction were a
+ two-phase or savepoint transaction.
+ For plain transactions, rollback() is a no-op
+ if the connection is invalidated, so while
+ it wasn't 100% clear if it should be a no-op,
+ at least now the interface is consistent.
+ - [feature] Added new support for remote "schemas":
+ - MetaData() accepts "schema" and "quote_schema"
+ arguments, which will be applied to the same-named
+ or Sequence which leaves these at their default
+ - Sequence accepts "quote_schema" argument
+ - tometadata() for Table will use the "schema"
+ of the incoming MetaData for the new Table
+ if the schema argument is explicitly "None"
+ - Added CreateSchema and DropSchema DDL
+ constructs - these accept just the string
+ name of a schema and a "quote" flag.
+ - When using default "schema" with MetaData,
+ ForeignKey will also assume the "default" schema
+ when locating remote table. This allows the "schema"
+ argument on MetaData to be applied to any
+ set of Table objects that otherwise don't have
+ - a "has_schema" method has been implemented
+ on dialect, but only works on Postgresql so far.
+ Courtesy Manlio Perillo, [ticket:1679]
+ - [feature] The "extend_existing" flag on Table
+ now allows for the reflection process to take
+ effect for a Table object that's already been
+ defined; when autoload=True and extend_existing=True
+ are both set, the full set of columns will be
+ reflected from the Table which will then
+ *overwrite* those columns already present,
+ rather than no activity occurring. Columns that
+ are present directly in the autoload run
+ will be used as always, however.
+ - [bug] Fixed bug whereby TypeDecorator would
+ return a stale value for _type_affinity, when
+ using a TypeDecorator that "switches" types,
+ like the CHAR/UUID type.
+ - [bug] Fixed bug whereby "order_by='foreign_key'"
+ option to Inspector.get_table_names
+ wasn't implementing the sort properly, replaced
+ with the existing sort algorithm
+ - [bug] the "name" of a column-level CHECK constraint,
+ if present, is now rendered in the CREATE TABLE
+ statement using "CONSTRAINT <name> CHECK <expression>".
+ - [bug] pyodbc-based dialects now parse the
+ pyodbc accurately as far as observed
+ pyodbc strings, including such gems
+ as "py3-3.0.1-beta4" [ticket:2318]
+ - [bug] Postgresql dialect memoizes that an ENUM of a
+ particular name was processed
+ during a create/drop sequence. This allows
+ a create/drop sequence to work without any
+ calls to "checkfirst", and also means with
+ "checkfirst" turned on it only needs to
+ check for the ENUM once. [ticket:2311]
+ - [feature] Added create_type constructor argument
+ to pg.ENUM. When False, no CREATE/DROP or
+ checking for the type will be performed as part
+ of a table create/drop event; only the
+ create()/drop)() methods called directly
+ will do this. Helps with Alembic "offline"
+ - [feature] lifted the restriction on SAVEPOINT
+ for SQL Server. All tests pass using it,
+ it's not known if there are deeper issues
+ - [bug] repaired the with_hint() feature which
+ wasn't implemented correctly on MSSQL -
+ usually used for the "WITH (NOLOCK)" hint
+ (which you shouldn't be using anyway !
+ use snapshot isolation instead :) )
+ - [bug] use new pyodbc version detection for
+ _need_decimal_fix option, [ticket:2318]
+ - [bug] don't cast "table name" as NVARCHAR
+ on SQL Server 2000. Still mostly in the dark
+ what incantations are needed to make PyODBC
+ work fully with FreeTDS 0.91 here, however.
+ - [bug] Decode incoming values when retrieving
+ list of index names and the names of columns
+ within those indexes. [ticket:2269]
+ - [bug] Unicode adjustments allow latest pymysql
+ (post 0.4) to pass 100% on Python 2.
+ - [feature] Added an example to the hybrid docs
+ of a "transformer" - a hybrid that returns a
+ query-transforming callable in combination
+ with a custom comparator. Uses a new method
+ on Query called with_transformation(). The use
+ case here is fairly experimental, but only
+ adds one line of code to Query.
+ - [bug] the @compiles decorator raises an
+ informative error message when no "default"
+ compilation handler is present, rather
+ - [bug] Fixed bug in history_meta.py example where
+ the "unique" flag was not removed from a
+ single-table-inheritance subclass which
+ generates columns to put up onto the base.
+ - Adjusted the "importlater" mechanism, which is
+ used internally to resolve import cycles,
+ such that the usage of __import__ is completed
+ when the import of sqlalchemy or sqlalchemy.orm
+ is done, thereby avoiding any usage of __import__
+ after the application starts new threads,
+ fixes [ticket:2279]. Also in 0.6.9.
+ - Improved query.join() such that the "left" side
+ can more flexibly be a non-ORM selectable,
+ such as a subquery. A selectable placed
+ in select_from() will now be used as the left
+ side, favored over implicit usage
+ If the join still fails based on lack of
+ foreign keys, the error message includes
+ this detail. Thanks to brianrhude
+ on IRC for the test case. [ticket:2298]
+ - Added after_soft_rollback() Session event. This
+ event fires unconditionally whenever rollback()
+ is called, regardless of if an actual DBAPI
+ level rollback occurred. This event
+ is specifically designed to allow operations
+ with the Session to proceed after a rollback
+ when the Session.is_active is True.
+ - added "adapt_on_names" boolean flag to orm.aliased()
+ construct. Allows an aliased() construct
+ to link the ORM entity to a selectable that contains
+ aggregates or other derived forms of a particular
+ attribute, provided the name is the same as that
+ of the entity mapped column.
+ - Added new flag expire_on_flush=False to column_property(),
+ marks those properties that would otherwise be considered
+ to be "readonly", i.e. derived from SQL expressions,
+ to retain their value after a flush has occurred, including
+ if the parent object itself was involved in an update.
+ - Enhanced the instrumentation in the ORM to support
+ Py3K's new argument style of "required kw arguments",
+ i.e. fn(a, b, *, c, d), fn(a, b, *args, c, d).
+ Argument signatures of mapped object's __init__
+ method will be preserved, including required kw rules.
+ - Fixed bug in unit of work whereby detection of
+ "cycles" among classes in highly interlinked patterns
+ would not produce a deterministic
+ result; thereby sometimes missing some nodes that
+ should be considered cycles and causing further
+ issues down the road. Note this bug is in 0.6
+ also; not backported at the moment.
+ - Fixed a variety of synonym()-related regressions
+ - making a synonym against a synonym now works.
+ - synonyms made against a relationship() can
+ be passed to query.join(), options sent
+ to query.options(), passed by name
+ to query.with_parent().
+ - Fixed bug whereby mapper.order_by attribute would
+ be ignored in the "inner" query within a
+ subquery eager load. [ticket:2287].
+ - Identity map .discard() uses dict.pop(,None)
+ internally instead of "del" to avoid KeyError/warning
+ during a non-determinate gc teardown [ticket:2267]
+ - Fixed regression in new composite rewrite where
+ deferred=True option failed due to missing
+ - Reinstated "comparator_factory" argument to
+ composite(), removed when 0.7 was released.
+ - Fixed bug in query.join() which would occur
+ in a complex multiple-overlapping path scenario,
+ where the same table could be joined to
+ twice. Thanks *much* to Dave Vitek
+ for the excellent fix here. [ticket:2247]
+ - Query will convert an OFFSET of zero when
+ slicing into None, so that needless OFFSET
+ clauses are not invoked.
+ - Repaired edge case where mapper would fail
+ to fully update internal state when a relationship
+ on a new mapper would establish a backref on the
+ - Fixed bug whereby if __eq__() was
+ redefined, a relationship many-to-one lazyload
+ would hit the __eq__() and fail. [ticket:2260]
+ Does not apply to 0.6.9.
+ - Calling class_mapper() and passing in an object
+ that is not a "type" (i.e. a class that could
+ potentially be mapped) now raises an informative
+ ArgumentError, rather than UnmappedClassError.
+ - New event hook, MapperEvents.after_configured().
+ Called after a configure() step has completed and
+ mappers were in fact affected. Theoretically this
+ event is called once per application, unless new mappings
+ are constructed after existing ones have been used
+ - When an open Session is garbage collected, the objects
+ within it which remain are considered detached again
+ when they are add()-ed to a new Session.