--*- coding: utf-8; fill-column: 68 -*-
-
-=======
-CHANGES
-=======
-
-0.8.0b1
-=======
-Changes noted below are specific to version 0.8.
-For changes that are in both 0.7 and 0.8, see below
-underneath "0.7.xx".
-
-- general
- - 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
- fully. [ticket:2433]
-
-- orm
- - [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
- the core.
-
- - [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.
- [ticket:2527]
-
- - [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.
- [ticket:2333]
-
- - [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(),
- contains_eager()
- [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.
- [ticket:2585]
-
- - [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.
- [ticket:2485]
-
- - [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
- Session.enable_relationship_loading(),
- supersedes relationship.load_on_pending.
- Both features should be avoided, however.
- [ticket:2372]
-
- - [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
- to [ticket:2229].
-
- - [feature] The presence of None in a mapped collection
- now raises an error during flush. Previously,
- None values in collections would be silently ignored.
- [ticket:2229]
-
- - [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
- in Core yet.
-
- - [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
- it deactivates.
-
- - [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.
- [ticket:2592]
-
- - [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.
- [ticket:2320]
-
- - [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
- query. Previously,
- 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.
- [ticket:2464]
-
- - [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
- flush events
- 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
- can't be guaranteed.
-
- - [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.
- [ticket:2526]
-
- - [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
- attributes in place.
- 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.
- [ticket:2526]
-
- - [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.
- [ticket:2338]
-
- - [feature] Can now provide class-bound attributes
- that override columns which are of any
- non-ORM type, not just descriptors.
- [ticket:2535]
-
- - [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()
- (use load=True)
-
- * sqlalchemy.orm.shard module
- (use sqlalchemy.ext.horizontal_shard)
-
-- engine
- - [feature] Connection event listeners can
- now be associated with individual
- Connection objects, not just Engine
- objects. [ticket:2511]
-
- - [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".
- [ticket:2462]
-
- - [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.
- [ticket:2397]
-
- - [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.
-
-- sql
- - [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.
- [ticket:1534]
-
- - [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
- optional operators.
-
- 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.
- [ticket:2276]
-
- - [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
- UnaryExpression().
-
- - [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
- in func.*.
-
- - [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.
- [ticket:2562]
-
- - [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,
- part of [ticket:2208]
-
- - [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.
- [ticket:2418]
-
- - [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.
- [ticket:2591]
-
- - [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.
- [ticket:2415]
-
- - [feature] Added "MATCH" clause to ForeignKey,
- ForeignKeyConstraint, courtesy Ryan Kelly.
- [ticket:2502]
-
- - [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
- passed.
-
- - [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.
- [ticket:2431]
-
- - [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
- removed [ticket:1729].
-
- - [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.
- [ticket:2410]
-
- - [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.
- [ticket:2594]
-
- - [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]
-
-- access
- - [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
- functionality now.
- https://bitbucket.org/zzzeek/sqlalchemy-access
-
-- maxdb
- - [moved] The MaxDB dialect, which hasn't been
- functional for several years, is
- moved out to a pending bitbucket project,
- https://bitbucket.org/zzzeek/sqlalchemy-maxdb.
-
-
-- sqlite
- - [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
- this. [ticket:2363]
-
-- mssql
- - [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
- compatibility.
-
-- postgresql
-
- - [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.
- [ticket:2441]
-
- - [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
- three reasons:
-
- 1. this is not an "official" API. Ideally
- an "official" API would allow custom type-handling
- callables at the dialect or global level
- in a generic way.
- 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
- default dialect level.
- 3. The reflection code here is only tested against
- simple types and probably has issues with more
- compositional types.
-
- patch courtesy Éric Lemoine.
-
-- firebird
- - [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
- literally instead.
-
- - [bug] Support for passing datetime as date when
- using the DateTime type with Firebird; other
- dialects support this.
-
- - [feature] An experimental dialect for the fdb
- driver is added, but is untested as I cannot
- get the fdb package to build. [ticket:2504]
-
-- mysql
- - [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.
- [ticket:2534]
-
-- oracle
- - [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
- of the table.
-
-- extensions
- - [removed] The SQLSoup extension is removed from
- SQLAlchemy, and is now an external project.
- See http://pypi.python.org/pypi/sqlsoup .
- [ticket:2262]
-
-0.7.7 - 0.7.xx
-==============
-0.8 development begins during 0.7.7 development.
-All relevant bug fixes
-and features listed below from version 0.7.7 on
-are also present in 0.8.
-
-0.7.10
-======
-- orm
- - [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.
- [ticket:2583]
-
-- oracle
- - [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]
-
-- mysql
- - [feature] Added "raise_on_warnings" flag to OurSQL
- dialect. [ticket:2523]
-
- - [feature] Added "read_timeout" flag to MySQLdb
- dialect. [ticket:2554]
-
-0.7.9
-=====
-- orm
- - [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
- explicitly.
-
- - [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
- error is raised now.
-
- - [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]
-
-- sql
- - [bug] Fixed the DropIndex construct to support
- an Index associated with a Table in a remote
- schema. [ticket:2571]
-
- - [bug] Fixed bug in over() construct whereby
- passing an empty list for either partition_by
- or order_by, as opposed to None, would fail
- to generate correctly.
- Courtesy Gunnlaugur Þór Briem.
- [ticket:2574]
-
- - [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.
- [ticket:2521]
-
- - [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.
- [ticket:2512]
-
- - [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
- UNION. [ticket:2552]
-
- - [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
- mechanism by which
- query(MyClass).from_statement(some_statement)
- 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]
-
-- engine
- - [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.
- [ticket:2553]
-
- - [bug] Fixed the repr() of Enum to include
- the "name" and "native_enum" flags. Helps
- Alembic autogenerate.
-
-- sqlite
- - [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""").
- [ticket:2568]
-
- - [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
- Richard Mitchell.
-
-- postgresql
- - [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.
- [ticket:2531].
-
- - [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]
-
-- mysql
- - [bug] Updated mysqlconnector interface to use
- updated "client flag" and "charset" APIs,
- courtesy David McNelis.
-
-- mssql
- - [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
- sayap [ticket:2538]
-
- - [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.
-
-0.7.8
-=====
-- orm
- - [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
- result. [ticket:2480]
-
- - [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].
-
-- sql
- - [bug] added BIGINT to types.__all__,
- BIGINT, BINARY, VARBINARY to sqlalchemy
- module namespace, plus test to ensure
- this breakage doesn't occur again.
- [ticket:2499]
-
- - [bug] Repaired common table expression
- rendering to function correctly when the
- SELECT statement contains UNION or other
- compound expressions, courtesy btbuilder.
- [ticket:2490]
-
- - [bug] Fixed bug whereby append_column()
- wouldn't function correctly on a cloned
- select() construct, courtesy
- Gunnlaugur Þór Briem. [ticket:2482]
-
-- engine
- - [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.
- [ticket:2503].
-
-- postgresql
- - [bug] removed unnecessary table clause when
- reflecting enums, [ticket:2510]. Courtesy
- Gunnlaugur Þór Briem.
-
-- oracle
- - [bug] Added ROWID to oracle.*, [ticket:2483]
-
-- mysql
- - [feature] Added a new dialect for Google App
- Engine. Courtesy Richie Foreman. [ticket:2484]
-
-
-0.7.7
-=====
-- orm
- - [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.
- [ticket:2477].
-
- - [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.
- [ticket:2449]
-
- - [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.
-
-- sql
- - [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
- of the cursor.
-
- - [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__,
- [ticket:2474]
-
-- mssql
- - [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
- or not.
-
- - [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"
- set to False.
-
- - [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.
- [ticket:2468]
-
-- postgresql
- - [feature] Added new for_update/with_lockmode()
- options for Postgresql: for_update="read"/
- with_lockmode("read"),
- for_update="read_nowait"/
- with_lockmode("read_nowait").
- These emit "FOR SHARE" and "FOR SHARE NOWAIT",
- respectively. Courtesy Diana Clarke
- [ticket:2445]
-
- - [bug] removed unnecessary table clause
- when reflecting domains, [ticket:2473]
-
-- mysql
- - [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
- Dairiki. [ticket:2460]
-
- - [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]
-
-- sqlite
-
- - [feature] Added SQLite execution option
- "sqlite_raw_colnames=True", will bypass
- attempts to remove "." from column names
- returned by SQLite cursor.description.
- [ticket:2475]
-
-0.7.6
=====
-- orm
- - [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.
- [ticket:2425]
-
- - [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.
- [ticket:2403]
-
- - [bug] Fixed bug whereby objects using
- attribute_mapped_collection or
- column_mapped_collection could not be
- pickled. [ticket:2409]
-
- - [bug] Fixed bug whereby MappedCollection
- would not get the appropriate collection
- instrumentation if it were only used
- in a custom subclass that used
- @collection.internally_instrumented.
- [ticket:2406]
-
- - [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.
- [ticket:2419]
-
- - [bug] Fixed the repr() for CascadeOptions to
- include refresh-expire. Also reworked
- CascadeOptions to be a <frozenset>.
- [ticket:2417]
-
- - [feature] Added the ability to query for
- Table-bound column names when using
- query(sometable).filter_by(colname=value).
- [ticket:2400]
-
- - [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
- as reflected.
-
- - [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.
- [ticket:2390]
-
- - [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]
-
-- sql
- - [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.
- [ticket:2398]
-
- - [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.
- [ticket:1859]
-
- - [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.
- [ticket:2413]
-
- - [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.
- [ticket:2402]
-
- - [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]
-
-- engine
- - [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
- for arguments.
-
- - [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
- to Engine, Connection:
-
- with engine.begin() as conn:
- <work with conn in a transaction>
-
- and:
-
- with engine.connect() as conn:
- <work with conn>
-
- Both close out the connection when done,
- commit or rollback transaction with errors
- on engine.begin().
-
-- sqlite
- - [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.
- [ticket:2432]
-
-- mssql
- - [feature] Added support for MSSQL INSERT,
- UPDATE, and DELETE table hints, using
- new with_hint() method on UpdateBase.
- [ticket:2430]
-
-- mysql
- - [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]
-
-- oracle
- - [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
- Decimal. [ticket:2399]
-
- - [bug] Added missing compilation support for
- LONG [ticket:2401]
-
- - [bug] Added 'LEVEL' to the list of reserved
- words for Oracle. [ticket:2435]
-
-- examples
- - [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
- columns clause, etc.
-
-0.7.5 (January 28, 2012)
+MOVED
=====
-- orm
- - [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 ??)
- [ticket:2367]
-
- - [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
- to load.
-
- - [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
- from [ticket:2356].
-
-- sql
- - [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.
- [ticket:2381]
-
-- engine
- - [bug] Added __reduce__ to StatementError,
- DBAPIError, column errors so that exceptions
- are pickleable, as when using multiprocessing.
- However, not
- 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
- set row. [ticket:2377]
-
- - [bug] Fixed bug in "mock" strategy whereby
- correct DDL visit method wasn't called, resulting
- in "CREATE/DROP SEQUENCE" statements being
- duplicated [ticket:2384]
-
-- sqlite
- - [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
- naming in any case.
-
- - [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.
-
-- mysql
- - [bug] fixed regexp that filters out warnings
- for non-reflected "PARTITION" directives,
- thanks to George Reilly [ticket:2376]
-
-- mssql
- - [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]
-
-- oracle
- - [bug] Added ORA-03135 to the never ending
- list of oracle "connection lost" errors
- [ticket:2388]
-
-- core
- - [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.
- [ticket:2379]
-
- - [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]
-
-- Py3K
- - [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.
- [ticket:2348]
-
-- examples
- - [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)
-=====
-- orm
- - [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
- case. [ticket:2264]
-
- - [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
- symbol [ticket:2304]
-
- - [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
- base [ticket:2312]
-
- - [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.
- [ticket:2328]
-
- - [bug] __table_args__ can now be passed as
- an empty tuple as well as an empty dict.
- [ticket:2339]. Thanks to Fayaz Yusuf Khan
- for the patch.
-
- - [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
- new kinds of values:
-
- - standalone expressions that aren't
- otherwise mapped
- - column_property() objects
- - string names of any column_property()
- or attribute name of a mapped Column
-
- The docs include an example using
- the case() construct, which is likely to be
- a common constructed used here.
- [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
- its use.
-
- - [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
- function.
-
-- sql
- - [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"
- anyway :).
-
- - [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]
-
-- engine
- - [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.
- [ticket:2317]
-
-- schema
- - [feature] Added new support for remote "schemas":
- - MetaData() accepts "schema" and "quote_schema"
- arguments, which will be applied to the same-named
- arguments of a Table
- or Sequence which leaves these at their default
- of ``None``.
- - 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 "schema".
- - 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.
- [ticket:1410]
-
- - [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>".
- [ticket:2305]
-
-- pyodbc
- - [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]
-
-- postgresql
- - [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"
- scripts.
-
-- mssql
- - [feature] lifted the restriction on SAVEPOINT
- for SQL Server. All tests pass using it,
- it's not known if there are deeper issues
- however. [ticket:822]
-
- - [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 :) )
- [ticket:2336]
-
- - [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.
- [ticket:2343]
-
- - [bug] Decode incoming values when retrieving
- list of index names and the names of columns
- within those indexes. [ticket:2269]
-
-- mysql
- - [bug] Unicode adjustments allow latest pymysql
- (post 0.4) to pass 100% on Python 2.
-
-- ext
- - [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
- than KeyError.
-
-- examples
- - [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.
-
-0.7.3
-=====
-- general
- - 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.
-
-- orm
- - 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
- of a mapped entity.
- 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.
- [ticket:2241]
-
- - 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.
- [ticket:2237]
-
- - 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.
- [ticket:2282]
-
- - Fixed a variety of synonym()-related regressions
- from 0.6:
- - 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].
- Also in 0.6.9.
-
- - 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
- import [ticket:2253]
-
- - Reinstated "comparator_factory" argument to
- composite(), removed when 0.7 was released.
- [ticket:2248]
-
- - 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
- first mapper.
-
- - 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.
- [ticket:2196]
-
- - 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
- already.
-
- - 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.
- This is accomplished by an extra check that the previous
- "session_key" doesn't actually exist among the pool
- of Sessions. [ticket:2281]
-
- - New declarative features:
- - __declare_last__() method, establishes an event
- listener for the class method that will be called
- when mappers are completed with the final "configure"
- step.
- - __abstract__ flag. The class will not be mapped
- at all when this flag is present on the class.
- - New helper classes ConcreteBase, AbstractConcreteBase.
- Allow concrete mappings using declarative which automatically
- set up the "polymorphic_union" when the "configure"
- mapper step is invoked.
- - The mapper itself has semi-private methods that allow
- the "with_polymorphic" selectable to be assigned
- to the mapper after it has already been configured.
- [ticket:2239]
-
- - Declarative will warn when a subclass' base uses
- @declared_attr for a regular column - this attribute
- does not propagate to subclasses. [ticket:2283]
-
- - The integer "id" used to link a mapped instance with
- its owning Session is now generated by a sequence
- generation function rather than id(Session), to
- eliminate the possibility of recycled id() values
- causing an incorrect result, no need to check that
- object actually in the session. [ticket:2280]
-
--sql
- - Behavioral improvement: empty
- conjunctions such as and_() and or_() will be
- flattened in the context of an enclosing conjunction,
- i.e. and_(x, or_()) will produce 'X' and not 'X AND
- ()'. [ticket:2257].
-
- - Fixed bug regarding calculation of "from" list
- for a select() element. The "from" calc is now
- delayed, so that if the construct uses a Column
- object that is not yet attached to a Table,
- but is later associated with a Table, it generates
- SQL using the table as a FROM. This change
- impacted fairly deeply the mechanics of how
- the FROM list as well as the "correlates" collection
- is calculated, as some "clause adaption" schemes
- (these are used very heavily in the ORM)
- were relying upon the fact that the "froms"
- collection would typically be cached before the
- adaption completed. The rework allows it
- such that the "froms" collection can be cleared
- and re-generated at any time. [ticket:2261]
-
- - Fixed bug whereby with_only_columns() method of
- Select would fail if a selectable were passed.
- [ticket:2270]. Also in 0.6.9.
-
-- schema
- - Modified Column.copy() to use _constructor(),
- which defaults to self.__class__, in order to
- create the new object. This allows easier support
- of subclassing Column. [ticket:2284]
-
- - Added a slightly nicer __repr__() to SchemaItem
- classes. Note the repr here can't fully support
- the "repr is the constructor" idea since schema
- items can be very deeply nested/cyclical, have
- late initialization of some things, etc.
- [ticket:2223]
-
-- engine
- - The recreate() method in all pool classes uses
- self.__class__ to get at the type of pool
- to produce, in the case of subclassing. Note
- there's no usual need to subclass pools.
- [ticket:2254]
-
- - Improvement to multi-param statement logging,
- long lists of bound parameter sets will be
- compressed with an informative indicator
- of the compression taking place. Exception
- messages use the same improved formatting.
- [ticket:2243]
-
- - Added optional "sa_pool_key" argument to
- pool.manage(dbapi).connect() so that serialization
- of args is not necessary.
-
- - The entry point resolution supported by
- create_engine() now supports resolution of
- individual DBAPI drivers on top of a built-in
- or entry point-resolved dialect, using the
- standard '+' notation - it's converted to
- a '.' before being resolved as an entry
- point. [ticket:2286]
-
- - Added an exception catch + warning for the
- "return unicode detection" step within connect,
- allows databases that crash on NVARCHAR to
- continue initializing, assuming no NVARCHAR
- type implemented. [ticket:2299]
-
-- types
- - Extra keyword arguments to the base Float
- type beyond "precision" and "asdecimal" are ignored;
- added a deprecation warning here and additional
- docs, related to [ticket:2258]
-
-- sqlite
- - Ensured that the same ValueError is raised for
- illegal date/time/datetime string parsed from
- the database regardless of whether C
- extensions are in use or not.
-
-- postgresql
- - Added "postgresql_using" argument to Index(), produces
- USING clause to specify index implementation for
- PG. [ticket:2290]. Thanks to Ryan P. Kelly for
- the patch.
-
- - Added client_encoding parameter to create_engine()
- when the postgresql+psycopg2 dialect is used;
- calls the psycopg2 set_client_encoding() method
- with the value upon connect. [ticket:1839]
-
- - Fixed bug related to [ticket:2141] whereby the
- same modified index behavior in PG 9 affected
- primary key reflection on a renamed column.
- [ticket:2291]. Also in 0.6.9.
-
- - Reflection functions for Table, Sequence no longer
- case insensitive. Names can be differ only in case
- and will be correctly distinguished. [ticket:2256]
-
- - Use an atomic counter as the "random number"
- source for server side cursor names;
- conflicts have been reported in rare cases.
-
- - Narrowed the assumption made when reflecting
- a foreign-key referenced table with schema in
- the current search path; an explicit schema will
- be applied to the referenced table only if
- it actually matches that of the referencing table,
- which also has an explicit schema. Previously
- it was assumed that "current" schema was synonymous
- with the full search_path. [ticket:2249]
-
-- mysql
- - a CREATE TABLE will put the COLLATE option
- after CHARSET, which appears to be part of
- MySQL's arbitrary rules regarding if it will actually
- work or not. [ticket:2225] Also in 0.6.9.
-
- - Added mysql_length parameter to Index construct,
- specifies "length" for indexes. [ticket:2293]
-
-- mssql
- - Changes to attempt support of FreeTDS 0.91 with
- Pyodbc. This includes that string binds are sent as
- Python unicode objects when FreeTDS 0.91 is detected,
- and a CAST(? AS NVARCHAR) is used when we detect
- for a table. However, I'd continue
- to characterize Pyodbc + FreeTDS 0.91 behavior as
- pretty crappy, there are still many queries such
- as used in reflection which cause a core dump on
- Linux, and it is not really usable at all
- on OSX, MemoryErrors abound and just plain broken
- unicode support. [ticket:2273]
-
- - The behavior of =/!= when comparing a scalar select
- to a value will no longer produce IN/NOT IN as of 0.8;
- this behavior is a little too heavy handed (use in_() if
- you want to emit IN) and now emits a deprecation warning.
- To get the 0.8 behavior immediately and remove the warning,
- a compiler recipe is given at
- http://www.sqlalchemy.org/docs/07/dialects/mssql.html#scalar-select-comparisons
- to override the behavior of visit_binary().
- [ticket:2277]
-
- - "0" is accepted as an argument for limit() which
- will produce "TOP 0". [ticket:2222]
-
-- oracle
- - Fixed ReturningResultProxy for zxjdbc dialect.
- [ticket:2272]. Regression from 0.6.
-
- - The String type now generates VARCHAR2 on Oracle
- which is recommended as the default VARCHAR.
- Added an explicit VARCHAR2 and NVARCHAR2 to the Oracle
- dialect as well. Using NVARCHAR still generates
- "NVARCHAR2" - there is no "NVARCHAR" on Oracle -
- this remains a slight breakage of the "uppercase types
- always give exactly that" policy. VARCHAR still
- generates "VARCHAR", keeping with the policy. If
- Oracle were to ever define "VARCHAR" as something
- different as they claim (IMHO this will never happen),
- the type would be available. [ticket:2252]
-
-- ext
- - SQLSoup will not be included in version 0.8
- of SQLAlchemy; while useful, we would like to
- keep SQLAlchemy itself focused on one ORM
- usage paradigm. SQLSoup will hopefully
- soon be superseded by a third party
- project. [ticket:2262]
-
- - Added local_attr, remote_attr, attr accessors
- to AssociationProxy, providing quick access
- to the proxied attributes at the class
- level. [ticket:2236]
-
- - Changed the update() method on association proxy
- dictionary to use a duck typing approach, i.e.
- checks for "keys", to discern between update({})
- and update((a, b)). Previously, passing a
- dictionary that had tuples as keys would be misinterpreted
- as a sequence. [ticket:2275]
-
-- examples
- - Adjusted dictlike-polymorphic.py example
- to apply the CAST such that it works on
- PG, other databases. [ticket:2266]
- Also in 0.6.9.
-
-0.7.2
-=====
-- orm
- - Feature enhancement: joined and subquery
- loading will now traverse already-present related
- objects and collections in search of unpopulated
- attributes throughout the scope of the eager load
- being defined, so that the eager loading that is
- specified via mappings or query options
- unconditionally takes place for the full depth,
- populating whatever is not already populated.
- Previously, this traversal would stop if a related
- object or collection were already present leading
- to inconsistent behavior (though would save on
- loads/cycles for an already-loaded graph). For a
- subqueryload, this means that the additional
- SELECT statements emitted by subqueryload will
- invoke unconditionally, no matter how much of the
- existing graph is already present (hence the
- controversy). The previous behavior of "stopping"
- is still in effect when a query is the result of
- an attribute-initiated lazyload, as otherwise an
- "N+1" style of collection iteration can become
- needlessly expensive when the same related object
- is encountered repeatedly. There's also an
- as-yet-not-public generative Query method
- _with_invoke_all_eagers()
- which selects old/new behavior [ticket:2213]
-
- - A rework of "replacement traversal" within
- the ORM as it alters selectables to be against
- aliases of things (i.e. clause adaption) includes
- a fix for multiply-nested any()/has() constructs
- against a joined table structure. [ticket:2195]
-
- - Fixed bug where query.join() + aliased=True
- from a joined-inh structure to itself on
- relationship() with join condition on the child
- table would convert the lead entity into the
- joined one inappropriately. [ticket:2234]
- Also in 0.6.9.
-
- - Fixed regression from 0.6 where Session.add()
- against an object which contained None in a
- collection would raise an internal exception.
- Reverted this to 0.6's behavior which is to
- accept the None but obviously nothing is
- persisted. Ideally, collections with None
- present or on append() should at least emit a
- warning, which is being considered for 0.8.
- [ticket:2205]
-
- - Load of a deferred() attribute on an object
- where row can't be located raises
- ObjectDeletedError instead of failing later
- on; improved the message in ObjectDeletedError
- to include other conditions besides a simple
- "delete". [ticket:2191]
-
- - Fixed regression from 0.6 where a get history
- operation on some relationship() based attributes
- would fail when a lazyload would emit; this could
- trigger within a flush() under certain conditions.
- [ticket:2224] Thanks to the user who submitted
- the great test for this.
-
- - Fixed bug apparent only in Python 3 whereby
- sorting of persistent + pending objects during
- flush would produce an illegal comparison,
- if the persistent object primary key
- is not a single integer. [ticket:2228]
- Also in 0.6.9
-
- - Fixed bug whereby the source clause
- used by query.join() would be inconsistent
- if against a column expression that combined
- multiple entities together. [ticket:2197]
- Also in 0.6.9
-
- - Fixed bug whereby if a mapped class
- redefined __hash__() or __eq__() to something
- non-standard, which is a supported use case
- as SQLA should never consult these,
- the methods would be consulted if the class
- was part of a "composite" (i.e. non-single-entity)
- result set. [ticket:2215]
- Also in 0.6.9.
-
- - Added public attribute ".validators" to
- Mapper, an immutable dictionary view of
- all attributes that have been decorated
- with the @validates decorator.
- [ticket:2240] courtesy Stefano Fontanelli
-
- - Fixed subtle bug that caused SQL to blow
- up if: column_property() against subquery +
- joinedload + LIMIT + order by the column
- property() occurred. [ticket:2188].
- Also in 0.6.9
-
- - The join condition produced by with_parent
- as well as when using a "dynamic" relationship
- against a parent will generate unique
- bindparams, rather than incorrectly repeating
- the same bindparam. [ticket:2207].
- Also in 0.6.9.
-
- - Added the same "columns-only" check to
- mapper.polymorphic_on as used when
- receiving user arguments to
- relationship.order_by, foreign_keys,
- remote_side, etc.
-
- - Fixed bug whereby comparison of column
- expression to a Query() would not call
- as_scalar() on the underlying SELECT
- statement to produce a scalar subquery,
- in the way that occurs if you called
- it on Query().subquery(). [ticket:2190]
-
- - Fixed declarative bug where a class inheriting
- from a superclass of the same name would fail
- due to an unnecessary lookup of the name
- in the _decl_class_registry. [ticket:2194]
-
- - Repaired the "no statement condition"
- assertion in Query which would attempt
- to raise if a generative method were called
- after from_statement() were called.
- [ticket:2199]. Also in 0.6.9.
-
-- sql
- - Fixed two subtle bugs involving column
- correspondence in a selectable,
- one with the same labeled subquery repeated, the other
- when the label has been "grouped" and
- loses itself. Affects [ticket:2188].
-
-- schema
- - New feature: with_variant() method on
- all types. Produces an instance of Variant(),
- a special TypeDecorator which will select
- the usage of a different type based on the
- dialect in use. [ticket:2187]
-
- - Added an informative error message when
- ForeignKeyConstraint refers to a column name in
- the parent that is not found. Also in 0.6.9.
-
- - Fixed bug whereby adaptation of old append_ddl_listener()
- function was passing unexpected **kw through
- to the Table event. Table gets no kws, the MetaData
- event in 0.6 would get "tables=somecollection",
- this behavior is preserved. [ticket:2206]
-
- - Fixed bug where "autoincrement" detection on
- Table would fail if the type had no "affinity"
- value, in particular this would occur when using
- the UUID example on the site that uses TypeEngine
- as the "impl".
-
- - Added an improved repr() to TypeEngine objects
- that will only display constructor args which
- are positional or kwargs that deviate
- from the default. [ticket:2209]
-
-- engine
- - Context manager provided by Connection.begin()
- will issue rollback() if the commit() fails,
- not just if an exception occurs.
-
- - Use urllib.parse_qsl() in Python 2.6 and above,
- no deprecation warning about cgi.parse_qsl()
- [ticket:1682]
-
- - Added mixin class sqlalchemy.ext.DontWrapMixin.
- User-defined exceptions of this type are never
- wrapped in StatementException when they
- occur in the context of a statement
- execution.
-
- - StatementException wrapping will display the
- original exception class in the message.
-
- - Failures on connect which raise dbapi.Error
- will forward the error to dialect.is_disconnect()
- and set the "connection_invalidated" flag if
- the dialect knows this to be a potentially
- "retryable" condition. Only Oracle ORA-01033
- implemented for now. [ticket:2201]
-
-- sqlite
- - SQLite dialect no longer strips quotes
- off of reflected default value, allowing
- a round trip CREATE TABLE to work.
- This is consistent with other dialects
- that also maintain the exact form of
- the default. [ticket:2189]
-
-- postgresql
- - Added new "postgresql_ops" argument to
- Index, allows specification of PostgreSQL
- operator classes for indexed columns.
- [ticket:2198] Courtesy Filip Zyzniewski.
-
-- mysql
- - Fixed OurSQL dialect to use ansi-neutral
- quote symbol "'" for XA commands instead
- of '"'. [ticket:2186]. Also in 0.6.9.
-
-- mssql
- - Adjusted the pyodbc dialect such that bound
- values are passed as bytes and not unicode
- if the "Easysoft" unix drivers are detected.
- This is the same behavior as occurs with
- FreeTDS. Easysoft appears to segfault
- if Python unicodes are passed under
- certain circumstances.
-
-- oracle
- - Added ORA-00028 to disconnect codes, use
- cx_oracle _Error.code to get at the code,
- [ticket:2200]. Also in 0.6.9.
-
- - Added ORA-01033 to disconnect codes, which
- can be caught during a connection
- event. [ticket:2201]
-
- - repaired the oracle.RAW type which did not
- generate the correct DDL. [ticket:2220]
- Also in 0.6.9.
-
- - added CURRENT to reserved word list.
- [ticket:2212] Also in 0.6.9.
-
--ext
- - Fixed bug in the mutable extension whereby
- if the same type were used twice in one
- mapping, the attributes beyond the first
- would not get instrumented.
-
- - Fixed bug in the mutable extension whereby
- if None or a non-corresponding type were set,
- an error would be raised. None is now accepted
- which assigns None to all attributes,
- illegal values raise ValueError.
-
-- examples
- - Repaired the examples/versioning test runner
- to not rely upon SQLAlchemy test libs,
- nosetests must be run from within
- examples/versioning to get around setup.cfg
- breaking it.
-
- - Tweak to examples/versioning to pick the
- correct foreign key in a multi-level
- inheritance situation.
-
- - Fixed the attribute shard example to check
- for bind param callable correctly in 0.7
- style.
-
-0.7.1
-=====
-- general
- - Added a workaround for Python bug 7511 where
- failure of C extension build does not
- raise an appropriate exception on Windows 64
- bit + VC express [ticket:2184]
-
-- orm
- - "delete-orphan" cascade is now allowed on
- self-referential relationships - this since
- SQLA 0.7 no longer enforces "parent with no
- child" at the ORM level; this check is left
- up to foreign key nullability.
- Related to [ticket:1912]
-
- - Repaired new "mutable" extension to propagate
- events to subclasses correctly; don't
- create multiple event listeners for
- subclasses either. [ticket:2180]
-
- - Modify the text of the message which occurs
- when the "identity" key isn't detected on
- flush, to include the common cause that
- the Column isn't set up to detect
- auto-increment correctly; [ticket:2170].
- Also in 0.6.8.
-
- - Fixed bug where transaction-level "deleted"
- collection wouldn't be cleared of expunged
- states, raising an error if they later
- became transient [ticket:2182].
- Also in 0.6.8.
-
-- sql
- - Fixed bug whereby metadata.reflect(bind)
- would close a Connection passed as a
- bind argument. Regression from 0.6.
-
- - Streamlined the process by which a Select
- determines what's in it's '.c' collection.
- Behaves identically, except that a
- raw ClauseList() passed to select([])
- (which is not a documented case anyway) will
- now be expanded into its individual column
- elements instead of being ignored.
-
-- engine
- - Deprecate schema/SQL-oriented methods on
- Connection/Engine that were never well known
- and are redundant: reflecttable(), create(),
- drop(), text(), engine.func
-
- - Adjusted the __contains__() method of
- a RowProxy result row such that no exception
- throw is generated internally;
- NoSuchColumnError() also will generate its
- message regardless of whether or not the column
- construct can be coerced to a string.
- [ticket:2178]. Also in 0.6.8.
-
-- sqlite
- - Accept None from cursor.fetchone() when
- "PRAGMA read_uncommitted" is called to determine
- current isolation mode at connect time and
- default to SERIALIZABLE; this to support SQLite
- versions pre-3.3.0 that did not have this
- feature. [ticket:2173]
-
-- postgresql
- - Some unit test fixes regarding numeric arrays,
- MATCH operator. A potential floating-point
- inaccuracy issue was fixed, and certain tests
- of the MATCH operator only execute within an
- EN-oriented locale for now. [ticket:2175].
- Also in 0.6.8.
-
-- mysql
- - Unit tests pass 100% on MySQL installed
- on windows.
-
- - Removed the "adjust casing" step that would
- fail when reflecting a table on MySQL
- on windows with a mixed case name. After some
- experimenting with a windows MySQL server, it's
- been determined that this step wasn't really
- helping the situation much; MySQL does not return
- FK names with proper casing on non-windows
- platforms either, and removing the step at
- least allows the reflection to act more like
- it does on other OSes. A warning here
- has been considered but its difficult to
- determine under what conditions such a warning
- can be raised, so punted on that for now -
- added some docs instead. [ticket:2181]
-
- - supports_sane_rowcount will be set to False
- if using MySQLdb and the DBAPI doesn't provide
- the constants.CLIENT module.
-
-0.7.0
-=======
-- This section documents those changes from 0.7b4
- to 0.7.0. For an overview of what's new in
- SQLAlchemy 0.7, see
- http://www.sqlalchemy.org/trac/wiki/07Migration
-
-- orm
- - Fixed regression introduced in 0.7b4 (!) whereby
- query.options(someoption("nonexistent name")) would
- fail to raise an error. Also added additional
- error catching for cases where the option would
- try to build off a column-based element, further
- fixed up some of the error messages tailored
- in [ticket:2069]
-
- - query.count() emits "count(*)" instead of
- "count(1)". [ticket:2162]
-
- - Fine tuning of Query clause adaptation when
- from_self(), union(), or other "select from
- myself" operation, such that plain SQL expression
- elements added to filter(), order_by() etc.
- which are present in the nested "from myself"
- query *will* be adapted in the same way an ORM
- expression element will, since these
- elements are otherwise not easily accessible.
- [ticket:2155]
-
- - Fixed bug where determination of "self referential"
- relationship would fail with no workaround
- for joined-inh subclass related to itself,
- or joined-inh subclass related to a subclass
- of that with no cols in the sub-sub class
- in the join condition. [ticket:2149]
- Also in 0.6.8.
-
- - mapper() will ignore non-configured foreign keys
- to unrelated tables when determining inherit
- condition between parent and child class,
- but will raise as usual for unresolved
- columns and table names regarding the inherited
- table. This is an enhanced generalization of
- behavior that was already applied to declarative
- previously. [ticket:2153] 0.6.8 has a more
- conservative version of this which doesn't
- fundamentally alter how join conditions
- are determined.
-
- - It is an error to call query.get() when the
- given entity is not a single, full class
- entity or mapper (i.e. a column). This is
- a deprecation warning in 0.6.8.
- [ticket:2144]
-
- - Fixed a potential KeyError which under some
- circumstances could occur with the identity
- map, part of [ticket:2148]
-
- - added Query.with_session() method, switches
- Query to use a different session.
-
- - horizontal shard query should use execution
- options per connection as per [ticket:2131]
-
- - a non_primary mapper will inherit the _identity_class
- of the primary mapper. This so that a non_primary
- established against a class that's normally in an
- inheritance mapping will produce results that are
- identity-map compatible with that of the primary
- mapper [ticket:2151] (also in 0.6.8)
-
- - Fixed the error message emitted for "can't
- execute syncrule for destination column 'q';
- mapper 'X' does not map this column" to
- reference the correct mapper. [ticket:2163].
- Also in 0.6.8.
-
- - polymorphic_union() gets a "cast_nulls" option,
- disables the usage of CAST when it renders
- the labeled NULL columns. [ticket:1502]
-
- - polymorphic_union() renders the columns in their
- original table order, as according to the first
- table/selectable in the list of polymorphic
- unions in which they appear. (which is itself
- an unordered mapping unless you pass an OrderedDict).
-
- - Fixed bug whereby mapper mapped to an anonymous
- alias would fail if logging were used, due to
- unescaped % sign in the alias name. [ticket:2171]
- Also in 0.6.8.
-
-- sql
- - Fixed bug whereby nesting a label of a select()
- with another label in it would produce incorrect
- exported columns. Among other things this would
- break an ORM column_property() mapping against
- another column_property(). [ticket:2167].
- Also in 0.6.8
-
- - Changed the handling in determination of join
- conditions such that foreign key errors are
- only considered between the two given tables.
- That is, t1.join(t2) will report FK errors
- that involve 't1' or 't2', but anything
- involving 't3' will be skipped. This affects
- join(), as well as ORM relationship and
- inherit condition logic.
-
- - Some improvements to error handling inside
- of the execute procedure to ensure auto-close
- connections are really closed when very
- unusual DBAPI errors occur.
-
- - metadata.reflect() and reflection.Inspector()
- had some reliance on GC to close connections
- which were internally procured, fixed this.
-
- - Added explicit check for when Column .name
- is assigned as blank string [ticket:2140]
-
- - Fixed bug whereby if FetchedValue was passed
- to column server_onupdate, it would not
- have its parent "column" assigned, added
- test coverage for all column default assignment
- patterns. [ticket:2147] also in 0.6.8
-
-- postgresql
- - Fixed the psycopg2_version parsing in the
- psycopg2 dialect.
-
- - Fixed bug affecting PG 9 whereby index reflection
- would fail if against a column whose name
- had changed. [ticket:2141]. Also in 0.6.8.
-
-- mssql
- - Fixed bug in MSSQL dialect whereby the aliasing
- applied to a schema-qualified table would leak
- into enclosing select statements [ticket:2169].
- Also in 0.6.8.
-
-- documentation
- - Removed the usage of the "collections.MutableMapping"
- abc from the ext.mutable docs as it was being used
- incorrectly and makes the example more difficult
- to understand in any case. [ticket:2152]
-
-- examples
- - removed the ancient "polymorphic association"
- examples and replaced with an updated set of
- examples that use declarative mixins,
- "generic_associations". Each presents an alternative
- table layout.
-
-- ext
- - Fixed bugs in sqlalchemy.ext.mutable extension where
- `None` was not appropriately handled, replacement
- events were not appropriately handled.
- [ticket:2143]
-
-0.7.0b4
-=======
-- general
- - Changes to the format of CHANGES, this file.
- The format changes have been applied to
- the 0.7 releases.
-
- - The "-declarative" changes will now be listed
- directly under the "-orm" section, as these
- are closely related.
-
- - The 0.5 series changes have been moved to
- the file CHANGES_PRE_06 which replaces
- CHANGES_PRE_05.
-
- - The changelog for 0.6.7 and subsequent within
- the 0.6 series is now listed only in the
- CHANGES file within the 0.6 branch.
- In the 0.7 CHANGES file (i.e. this file), all the
- 0.6 changes are listed inline within the 0.7
- section in which they were also applied
- (since all 0.6 changes are in 0.7 as well).
- Changes that apply to an 0.6 version here
- are noted as are if any differences in
- implementation/behavior are present.
-
-- orm
- - Some fixes to "evaulate" and "fetch" evaluation
- when query.update(), query.delete() are called.
- The retrieval of records is done after autoflush
- in all cases, and before update/delete is
- emitted, guarding against unflushed data present
- as well as expired objects failing during
- the evaluation. [ticket:2122]
-
- - Reworded the exception raised when a flush
- is attempted of a subclass that is not polymorphic
- against the supertype. [ticket:2063]
-
- - Still more wording adjustments when a query option
- can't find the target entity. Explain that the
- path must be from one of the root entities.
-
- - Some fixes to the state handling regarding
- backrefs, typically when autoflush=False, where
- the back-referenced collection wouldn't
- properly handle add/removes with no net
- change. Thanks to Richard Murri for the
- test case + patch. [ticket:2123]
- (also in 0.6.7).
-
- - Added checks inside the UOW to detect the unusual
- condition of being asked to UPDATE or DELETE
- on a primary key value that contains NULL
- in it. [ticket:2127]
-
- - Some refinements to attribute history. More
- changes are pending possibly in 0.8, but
- for now history has been modified such that
- scalar history doesn't have a "side effect"
- of populating None for a non-present value.
- This allows a slightly better ability to
- distinguish between a None set and no actual
- change, affects [ticket:2127] as well.
-
- - a "having" clause would be copied from the
- inside to the outside query if from_self()
- were used; in particular this would break
- an 0.7 style count() query [ticket:2130].
- (also in 0.6.7)
-
- - the Query.execution_options() method now passes
- those options to the Connection rather than
- the SELECT statement, so that all available
- options including isolation level and
- compiled cache may be used. [ticket:2131]
-
-- sql
- - The "compiled_cache" execution option now raises
- an error when passed to a SELECT statement
- rather than a Connection. Previously it was
- being ignored entirely. We may look into
- having this option work on a per-statement
- level at some point. [ticket:2131]
-
- - Restored the "catchall" constructor on the base
- TypeEngine class, with a deprecation warning.
- This so that code which does something like
- Integer(11) still succeeds.
-
- - Fixed regression whereby MetaData() coming
- back from unpickling did not keep track of
- new things it keeps track of now, i.e.
- collection of Sequence objects, list
- of schema names. [ticket:2104]
-
- - The limit/offset keywords to select() as well
- as the value passed to select.limit()/offset()
- will be coerced to integer. [ticket:2116]
- (also in 0.6.7)
-
- - fixed bug where "from" clause gathering from an
- over() clause would be an itertools.chain() and
- not a list, causing "can only concatenate list"
- TypeError when combined with other clauses.
-
- - Fixed incorrect usage of "," in over() clause
- being placed between the "partition" and "order by"
- clauses. [ticket:2134]
-
- - Before/after attach events for PrimaryKeyConstraint
- now function, tests added for before/after events
- on all constraint types. [ticket:2105]
-
- - Added explicit true()/false() constructs to expression
- lib - coercion rules will intercept "False"/"True"
- into these constructs. In 0.6, the constructs were
- typically converted straight to string, which was
- no longer accepted in 0.7. [ticket:2117]
-
-- engine
- - The C extension is now enabled by default on CPython
- 2.x with a fallback to pure python if it fails to
- compile. [ticket:2129]
-
-- schema
- - The 'useexisting' flag on Table has been superceded
- by a new pair of flags 'keep_existing' and
- 'extend_existing'. 'extend_existing' is equivalent
- to 'useexisting' - the existing Table is returned,
- and additional constructor elements are added.
- With 'keep_existing', the existing Table is returned,
- but additional constructor elements are not added -
- these elements are only applied when the Table
- is newly created. [ticket:2109]
-
-- types
- - REAL has been added to the core types. Supported
- by Postgresql, SQL Server, MySQL, SQLite. Note
- that the SQL Server and MySQL versions, which
- add extra arguments, are also still available
- from those dialects. [ticket:2081]
-
--event
- - Added @event.listens_for() decorator, given
- target + event name, applies the decorated
- function as a listener. [ticket:2106]
-
-- pool
- - AssertionPool now stores the traceback indicating
- where the currently checked out connection was
- acquired; this traceback is reported within
- the assertion raised upon a second concurrent
- checkout; courtesy Gunnlaugur Briem
- [ticket:2103]
-
- - The "pool.manage" feature doesn't use pickle
- anymore to hash the arguments for each pool.
-
-- sqlite
- - Fixed bug where reflection of foreign key
- created as "REFERENCES <tablename>" without
- col name would fail. [ticket:2115]
- (also in 0.6.7)
-
-- postgresql
- - Psycopg2 for Python 3 is now supported.
-
- - Fixed support for precision numerics when using
- pg8000. [ticket:2132]
-
-- oracle
- - Using column names that would require quotes
- for the column itself or for a name-generated
- bind parameter, such as names with special
- characters, underscores, non-ascii characters,
- now properly translate bind parameter keys when
- talking to cx_oracle. [ticket:2100] (Also
- in 0.6.7)
-
- - Oracle dialect adds use_binds_for_limits=False
- create_engine() flag, will render the LIMIT/OFFSET
- values inline instead of as binds, reported to
- modify the execution plan used by Oracle.
- [ticket:2116] (Also in 0.6.7)
-
-- documentation
- - Documented SQLite DATE/TIME/DATETIME types.
- [ticket:2029] (also in 0.6.7)
-
- - Fixed mutable extension docs to show the
- correct type-association methods.
- [ticket:2118]
-
-0.7.0b3
-=======
-- general
- - Lots of fixes to unit tests when run under Pypy
- (courtesy Alex Gaynor).
-
-- orm
- - Changed the underlying approach to query.count().
- query.count() is now in all cases exactly:
-
- query.
- from_self(func.count(literal_column('1'))).
- scalar()
-
- That is, "select count(1) from (<full query>)".
- This produces a subquery in all cases, but
- vastly simplifies all the guessing count()
- tried to do previously, which would still
- fail in many scenarios particularly when
- joined table inheritance and other joins
- were involved. If the subquery produced
- for an otherwise very simple count is really
- an issue, use query(func.count()) as an
- optimization. [ticket:2093]
-
- - some changes to the identity map regarding
- rare weakref callbacks during iterations.
- The mutex has been removed as it apparently
- can cause a reentrant (i.e. in one thread) deadlock,
- perhaps when gc collects objects at the point of
- iteration in order to gain more memory. It is hoped
- that "dictionary changed during iteration" will
- be exceedingly rare as iteration methods internally
- acquire the full list of objects in a single values()
- call. Note 0.6.7 has a more conservative fix here
- which still keeps the mutex in place. [ticket:2087]
-
- - A tweak to the unit of work causes it to order
- the flush along relationship() dependencies even if
- the given objects don't have any inter-attribute
- references in memory, which was the behavior in
- 0.5 and earlier, so a flush of Parent/Child with
- only foreign key/primary key set will succeed.
- This while still maintaining 0.6 and above's not
- generating a ton of useless internal dependency
- structures within the flush that don't correspond
- to state actually within the current flush.
- [ticket:2082]
-
- - Improvements to the error messages emitted when
- querying against column-only entities in conjunction
- with (typically incorrectly) using loader options,
- where the parent entity is not fully present.
- [ticket:2069]
-
- - Fixed bug in query.options() whereby a path
- applied to a lazyload using string keys could
- overlap a same named attribute on the wrong
- entity. Note 0.6.7 has a more conservative fix
- to this. [ticket:2098]
-
-- declarative
- - Arguments in __mapper_args__ that aren't "hashable"
- aren't mistaken for always-hashable, possibly-column
- arguments. [ticket:2091] (also in 0.6.7)
-
-- sql
- - Added a fully descriptive error message for the
- case where Column is subclassed and _make_proxy()
- fails to make a copy due to TypeError on the
- constructor. The method _constructor should
- be implemented in this case.
-
- - Added new event "column_reflect" for Table objects.
- Receives the info dictionary about a Column before
- the object is generated within reflection, and allows
- modification to the dictionary for control over
- most aspects of the resulting Column including
- key, name, type, info dictionary. [ticket:2095]
-
- - To help with the "column_reflect" event being used
- with specific Table objects instead of all instances
- of Table, listeners can be added to a Table object
- inline with its construction using a new argument
- "listeners", a list of tuples of the form
- (<eventname>, <fn>), which are applied to the Table
- before the reflection process begins.
-
- - Added new generic function "next_value()", accepts
- a Sequence object as its argument and renders the
- appropriate "next value" generation string on the
- target platform, if supported. Also provides
- ".next_value()" method on Sequence itself.
- [ticket:2085]
-
- - func.next_value() or other SQL expression can
- be embedded directly into an insert() construct,
- and if implicit or explicit "returning" is used
- in conjunction with a primary key column,
- the newly generated value will be present in
- result.inserted_primary_key. [ticket:2084]
-
- - Added accessors to ResultProxy "returns_rows",
- "is_insert" [ticket:2089] (also in 0.6.7)
-
-- engine
- - Fixed AssertionPool regression bug. [ticket:2097]
-
- - Changed exception raised to ArgumentError when an
- invalid dialect is specified. [ticket:2060]
-
-- postgresql
- - Added RESERVED_WORDS for postgresql dialect. [ticket:2092]
- (also in 0.6.7)
-
- - Fixed the BIT type to allow a "length" parameter, "varying"
- parameter. Reflection also fixed. [ticket:2073]
- (also in 0.6.7)
-
-- mssql
- - Rewrote the query used to get the definition of a view,
- typically when using the Inspector interface, to
- use sys.sql_modules instead of the information schema,
- thereby allowing views definitions longer than 4000
- characters to be fully returned. [ticket:2071]
- (also in 0.6.7)
-
-- firebird
- - The "implicit_returning" flag on create_engine() is
- honored if set to False. [ticket:2083] (also in 0.6.7)
-
-- informix
-
- - Added RESERVED_WORDS informix dialect. [ticket:2092]
- (also in 0.6.7)
-
-- ext
- - The horizontal_shard ShardedSession class accepts the common
- Session argument "query_cls" as a constructor argument,
- to enable further subclassing of ShardedQuery.
- [ticket:2090] (also in 0.6.7)
-
-- examples
- - Updated the association, association proxy examples
- to use declarative, added a new example
- dict_of_sets_with_default.py, a "pushing the envelope"
- example of association proxy.
-
- - The Beaker caching example allows a "query_cls" argument
- to the query_callable() function. [ticket:2090]
- (also in 0.6.7)
-
-0.7.0b2
-========
-- orm
- - Fixed bug whereby Session.merge() would call the
- load() event with one too few arguments.
- [ticket:2053]
-
- - Added logic which prevents the generation of
- events from a MapperExtension or SessionExtension
- from generating do-nothing events for all the methods
- not overridden. [ticket:2052]
-
-- declarative
- - Fixed regression whereby composite() with
- Column objects placed inline would fail
- to initialize. The Column objects can now
- be inline with the composite() or external
- and pulled in via name or object ref.
- [ticket:2058]
-
- - Fix error message referencing old @classproperty
- name to reference @declared_attr [ticket:2061]
- (also in 0.6.7)
-
- - the dictionary at the end of the __table_args__
- tuple is now optional. [ticket:1468]
-
-- sql
- - Renamed the EngineEvents event class to
- ConnectionEvents. As these classes are never
- accessed directly by end-user code, this strictly
- is a documentation change for end users. Also
- simplified how events get linked to engines
- and connections internally. [ticket:2059]
-
- - The Sequence() construct, when passed a MetaData()
- object via its 'metadata' argument, will be
- included in CREATE/DROP statements within
- metadata.create_all() and metadata.drop_all(),
- including "checkfirst" logic. [ticket:2055]
-
- - The Column.references() method now returns True
- if it has a foreign key referencing the
- given column exactly, not just it's parent
- table. [ticket:2064]
-
-- postgresql
- - Fixed regression from 0.6 where SMALLINT and
- BIGINT types would both generate SERIAL
- on an integer PK column, instead of
- SMALLINT and BIGSERIAL [ticket:2065]
-
-- ext
- - Association proxy now has correct behavior for
- any(), has(), and contains() when proxying
- a many-to-one scalar attribute to a one-to-many
- collection (i.e. the reverse of the 'typical'
- association proxy use case) [ticket:2054]
-
-- examples
- - Beaker example now takes into account 'limit'
- and 'offset', bind params within embedded
- FROM clauses (like when you use union() or
- from_self()) when generating a cache key.
-
-0.7.0b1
-=======
-- Detailed descriptions of each change below are
- described at:
- http://www.sqlalchemy.org/trac/wiki/07Migration
-
-- general
- - New event system, supercedes all extensions, listeners,
- etc. [ticket:1902]
-
- - Logging enhancements
- [ticket:1926]
-
- - Setup no longer installs a Nose plugin
- [ticket:1949]
-
- - The "sqlalchemy.exceptions" alias in sys.modules
- has been removed. Base SQLA exceptions are
- available via "from sqlalchemy import exc".
- The "exceptions" alias for "exc" remains in
- "sqlalchemy" for now, it's just not patched into
- sys.modules.
-
-- orm
- - More succinct form of query.join(target, onclause)
- [ticket:1923]
-
- - Hybrid Attributes, implements/supercedes synonym()
- [ticket:1903]
-
- - Rewrite of composites [ticket:2008]
-
- - Mutation Event Extension, supercedes "mutable=True"
-
- - PickleType and ARRAY mutability turned off by default
- [ticket:1980]
-
- - Simplified polymorphic_on assignment
- [ticket:1895]
-
- - Flushing of Orphans that have no parent is allowed
- [ticket:1912]
-
- - Adjusted flush accounting step to occur before
- the commit in the case of autocommit=True. This allows
- autocommit=True to work appropriately with
- expire_on_commit=True, and also allows post-flush session
- hooks to operate in the same transactional context
- as when autocommit=False. [ticket:2041]
-
- - Warnings generated when collection members, scalar referents
- not part of the flush
- [ticket:1973]
-
- - Non-`Table`-derived constructs can be mapped
- [ticket:1876]
-
- - Tuple label names in Query Improved
- [ticket:1942]
-
- - Mapped column attributes reference the most specific
- column first
- [ticket:1892]
-
- - Mapping to joins with two or more same-named columns
- requires explicit declaration
- [ticket:1896]
-
- - Mapper requires that polymorphic_on column be present
- in the mapped selectable
- [ticket:1875]
-
- - compile_mappers() renamed configure_mappers(), simplified
- configuration internals
- [ticket:1966]
-
- - the aliased() function, if passed a SQL FromClause element
- (i.e. not a mapped class), will return element.alias()
- instead of raising an error on AliasedClass. [ticket:2018]
-
- - Session.merge() will check the version id of the incoming
- state against that of the database, assuming the mapping
- uses version ids and incoming state has a version_id
- assigned, and raise StaleDataError if they don't
- match. [ticket:2027]
-
- - Session.connection(), Session.execute() accept 'bind',
- to allow execute/connection operations to participate
- in the open transaction of an engine explicitly.
- [ticket:1996]
-
- - Query.join(), Query.outerjoin(), eagerload(),
- eagerload_all(), others no longer allow lists
- of attributes as arguments (i.e. option([x, y, z])
- form, deprecated since 0.5)
-
- - ScopedSession.mapper is removed (deprecated since 0.5).
-
- - Horizontal shard query places 'shard_id' in
- context.attributes where it's accessible by the
- "load()" event. [ticket:2031]
-
- - A single contains_eager() call across
- multiple entities will indicate all collections
- along that path should load, instead of requiring
- distinct contains_eager() calls for each endpoint
- (which was never correctly documented).
- [ticket:2032]
-
- - The "name" field used in orm.aliased() now renders
- in the resulting SQL statement.
-
- - Session weak_instance_dict=False is deprecated.
- [ticket:1473]
-
- - An exception is raised in the unusual case that an
- append or similar event on a collection occurs after
- the parent object has been dereferenced, which
- prevents the parent from being marked as "dirty"
- in the session. Was a warning in 0.6.6.
- [ticket:2046]
-
- - Query.distinct() now accepts column expressions
- as *args, interpreted by the Postgresql dialect
- as DISTINCT ON (<expr>). [ticket:1069]
-
- - Additional tuning to "many-to-one" relationship
- loads during a flush(). A change in version 0.6.6
- ([ticket:2002]) required that more "unnecessary" m2o
- loads during a flush could occur. Extra loading modes have
- been added so that the SQL emitted in this
- specific use case is trimmed back, while still
- retrieving the information the flush needs in order
- to not miss anything. [ticket:2049]
-
- - the value of "passive" as passed to
- attributes.get_history() should be one of the
- constants defined in the attributes package. Sending
- True or False is deprecated.
-
- - Added a `name` argument to `Query.subquery()`, to allow
- a fixed name to be assigned to the alias object.
- [ticket:2030] (also in 0.6.7)
-
- - A warning is emitted when a joined-table inheriting mapper
- has no primary keys on the locally mapped table
- (but has pks on the superclass table). [ticket:2019]
- (also in 0.6.7)
-
- - Fixed bug where "middle" class in a polymorphic hierarchy
- would have no 'polymorphic_on' column if it didn't also
- specify a 'polymorphic_identity', leading to strange
- errors upon refresh, wrong class loaded when querying
- from that target. Also emits the correct WHERE criterion
- when using single table inheritance. [ticket:2038]
- (also in 0.6.7)
-
- - Fixed bug where a column with a SQL or server side default
- that was excluded from a mapping with include_properties
- or exclude_properties would result in UnmappedColumnError.
- [ticket:1995] (also in 0.6.7)
-
- - A warning is emitted in the unusual case that an
- append or similar event on a collection occurs after
- the parent object has been dereferenced, which
- prevents the parent from being marked as "dirty"
- in the session. This will be an exception in 0.7.
- [ticket:2046] (also in 0.6.7)
-
-- declarative
- - Added an explicit check for the case that the name
- 'metadata' is used for a column attribute on a
- declarative class. [ticket:2050] (also in 0.6.7)
-
-- sql
- - Added over() function, method to FunctionElement
- classes, produces the _Over() construct which
- in turn generates "window functions", i.e.
- "<window function> OVER (PARTITION BY <partition by>,
- ORDER BY <order by>)".
- [ticket:1844]
-
- - LIMIT/OFFSET clauses now use bind parameters
- [ticket:805]
-
- - select.distinct() now accepts column expressions
- as *args, interpreted by the Postgresql dialect
- as DISTINCT ON (<expr>). Note this was already
- available via passing a list to the `distinct`
- keyword argument to select(). [ticket:1069]
-
- - select.prefix_with() accepts multiple expressions
- (i.e. *expr), 'prefix' keyword argument to select()
- accepts a list or tuple.
-
- - Passing a string to the `distinct` keyword argument
- of `select()` for the purpose of emitting special
- MySQL keywords (DISTINCTROW etc.) is deprecated -
- use `prefix_with()` for this.
-
- - TypeDecorator works with primary key columns
- [ticket:2005] [ticket:2006]
-
- - DDL() constructs now escape percent signs
- [ticket:1897]
-
- - Table.c / MetaData.tables refined a bit, don't allow direct
- mutation [ticket:1893] [ticket:1917]
-
- - Callables passed to `bindparam()` don't get evaluated
- [ticket:1950]
-
- - types.type_map is now private, types._type_map
- [ticket:1870]
-
- - Non-public Pool methods underscored
- [ticket:1982]
-
- - Added NULLS FIRST and NULLS LAST support. It's implemented
- as an extension to the asc() and desc() operators, called
- nullsfirst() and nullslast(). [ticket:723]
-
- - The Index() construct can be created inline with a Table
- definition, using strings as column names, as an alternative
- to the creation of the index outside of the Table.
-
- - execution_options() on Connection accepts
- "isolation_level" argument, sets transaction isolation
- level for that connection only until returned to the
- connection pool, for thsoe backends which support it
- (SQLite, Postgresql) [ticket:2001]
-
- - A TypeDecorator of Integer can be used with a primary key
- column, and the "autoincrement" feature of various dialects
- as well as the "sqlite_autoincrement" flag will honor
- the underlying database type as being Integer-based.
- [ticket:2005]
-
- - Established consistency when server_default is present
- on an Integer PK column. SQLA doesn't pre-fetch these,
- nor do they come back in cursor.lastrowid (DBAPI).
- Ensured all backends consistently return None
- in result.inserted_primary_key for these. Regarding
- reflection for this case, reflection of an int PK col
- with a server_default sets the "autoincrement" flag to False,
- except in the case of a PG SERIAL col where we detected a
- sequence default. [ticket:2020] [ticket:2021]
-
- - Result-row processors are applied to pre-executed SQL
- defaults, as well as cursor.lastrowid, when determining
- the contents of result.inserted_primary_key.
- [ticket:2006]
-
- - Bind parameters present in the "columns clause" of a select
- are now auto-labeled like other "anonymous" clauses,
- which among other things allows their "type" to be meaningful
- when the row is fetched, as in result row processors.
-
- - TypeDecorator is present in the "sqlalchemy" import space.
-
- - Non-DBAPI errors which occur in the scope of an `execute()`
- call are now wrapped in sqlalchemy.exc.StatementError,
- and the text of the SQL statement and repr() of params
- is included. This makes it easier to identify statement
- executions which fail before the DBAPI becomes
- involved. [ticket:2015]
-
- - The concept of associating a ".bind" directly with a
- ClauseElement has been explicitly moved to Executable,
- i.e. the mixin that describes ClauseElements which represent
- engine-executable constructs. This change is an improvement
- to internal organization and is unlikely to affect any
- real-world usage. [ticket:2048]
-
- - Column.copy(), as used in table.tometadata(), copies the
- 'doc' attribute. [ticket:2028] (also in 0.6.7)
-
- - Added some defs to the resultproxy.c extension so that
- the extension compiles and runs on Python 2.4.
- [ticket:2023] (also in 0.6.7)
-
- - The compiler extension now supports overriding the default
- compilation of expression._BindParamClause including that
- the auto-generated binds within the VALUES/SET clause
- of an insert()/update() statement will also use the new
- compilation rules. [ticket:2042] (also in 0.6.7)
-
--sqlite
- - SQLite dialect now uses `NullPool` for file-based databases
- [ticket:1921]
-
- - The path given as the location of a sqlite database is now
- normalized via os.path.abspath(), so that directory changes
- within the process don't affect the ultimate location
- of a relative file path. [ticket:2036]
-
-- postgresql
- - When explicit sequence execution derives the name
- of the auto-generated sequence of a SERIAL column,
- which currently only occurs if implicit_returning=False,
- now accommodates if the table + column name is greater
- than 63 characters using the same logic Postgresql uses.
- [ticket:1083] (also in 0.6.7)
-
- - Added an additional libpq message to the list of "disconnect"
- exceptions, "could not receive data from server"
- [ticket:2044] (also in 0.6.7)
-
-- mssql
- - the String/Unicode types, and their counterparts VARCHAR/
- NVARCHAR, emit "max" as the length when no length is
- specified, so that the default length, normally '1'
- as per SQL server documentation, is instead
- 'unbounded'. This also occurs for the VARBINARY type.
- [ticket:1833].
-
- This behavior makes these types more closely compatible
- with Postgresql's VARCHAR type which is similarly unbounded
- when no length is specified.
-
-- mysql
- - New DBAPI support for pymysql, a pure Python port
- of MySQL-python. [ticket:1991]
-
- - oursql dialect accepts the same "ssl" arguments in
- create_engine() as that of MySQLdb. [ticket:2047]
- (also in 0.6.7)
-
-- firebird
- - Some adjustments so that Interbase is supported as well.
- FB/Interbase version idents are parsed into a structure
- such as (8, 1, 1, 'interbase') or (2, 1, 588, 'firebird')
- so they can be distinguished. [ticket:1885]
-
-- drizzle
- - New dialect for Drizzle, a MySQL variant. Uses MySQL-python
- for the DBAPI. [ticket:2003]
-
-0.6.7 - 0.6.xx
-==============
-
-Changes which apply to 0.6.7 and subsequent versions of 0.6
-are listed in the CHANGES file within the 0.6 branch. All
-those changes which are also in the 0.7 series (which is typically
-all of them) are listed inline within the 0.7 changes above,
-those which apply to an 0.6 release are noted.
-
-0.6.6
-=====
-- orm
- - Fixed bug whereby a non-"mutable" attribute modified event
- which occurred on an object that was clean except for
- preceding mutable attribute changes would fail to strongly
- reference itself in the identity map. This would cause the
- object to be garbage collected, losing track of any changes
- that weren't previously saved in the "mutable changes"
- dictionary.
-
- - Fixed bug whereby "passive_deletes='all'" wasn't passing
- the correct symbols to lazy loaders during flush, thereby
- causing an unwarranted load. [ticket:2013]
-
- - Fixed bug which prevented composite mapped
- attributes from being used on a mapped select statement.
- [ticket:1997]. Note the workings of composite are slated to
- change significantly in 0.7.
-
- - active_history flag also added to composite().
- The flag has no effect in 0.6, but is instead
- a placeholder flag for forwards compatibility,
- as it applies in 0.7 for composites.
- [ticket:1976]
-
- - Fixed uow bug whereby expired objects passed to
- Session.delete() would not have unloaded references
- or collections taken into account when deleting
- objects, despite passive_deletes remaining at
- its default of False. [ticket:2002]
-
- - A warning is emitted when version_id_col is specified
- on an inheriting mapper when the inherited mapper
- already has one, if those column expressions are not
- the same. [ticket:1987]
-
- - "innerjoin" flag doesn't take effect along the chain
- of joinedload() joins if a previous join in that chain
- is an outer join, thus allowing primary rows without
- a referenced child row to be correctly returned
- in results. [ticket:1954]
-
- - Fixed bug regarding "subqueryload" strategy whereby
- strategy would fail if the entity was an aliased()
- construct. [ticket:1964]
-
- - Fixed bug regarding "subqueryload" strategy whereby
- the join would fail if using a multi-level load
- of the form from A->joined-subclass->C [ticket:2014]
-
- - Fixed indexing of Query objects by -1. It was erroneously
- transformed to the empty slice -1:0 that resulted in
- IndexError. [ticket:1968]
-
- - The mapper argument "primary_key" can be passed as a
- single column as well as a list or tuple. [ticket:1971]
- The documentation examples that illustrated it as a
- scalar value have been changed to lists.
-
- - Added active_history flag to relationship()
- and column_property(), forces attribute events to
- always load the "old" value, so that it's available to
- attributes.get_history(). [ticket:1961]
-
- - Query.get() will raise if the number of params
- in a composite key is too large, as well as too
- small. [ticket:1977]
-
- - Backport of "optimized get" fix from 0.7,
- improves the generation of joined-inheritance
- "load expired row" behavior. [ticket:1992]
-
- - A little more verbiage to the "primaryjoin" error,
- in an unusual condition that the join condition
- "works" for viewonly but doesn't work for non-viewonly,
- and foreign_keys wasn't used - adds "foreign_keys" to
- the suggestion. Also add "foreign_keys" to the
- suggestion for the generic "direction" error.
-
-- sql
- - Fixed operator precedence rules for multiple
- chains of a single non-associative operator.
- I.e. "x - (y - z)" will compile as "x - (y - z)"
- and not "x - y - z". Also works with labels,
- i.e. "x - (y - z).label('foo')"
- [ticket:1984]
-
- - The 'info' attribute of Column is copied during
- Column.copy(), i.e. as occurs when using columns
- in declarative mixins. [ticket:1967]
-
- - Added a bind processor for booleans which coerces
- to int, for DBAPIs such as pymssql that naively call
- str() on values.
-
- - CheckConstraint will copy its 'initially', 'deferrable',
- and '_create_rule' attributes within a copy()/tometadata()
- [ticket:2000]
-
-- engine
- - The "unicode warning" against non-unicode bind data
- is now raised only when the
- Unicode type is used explictly; not when
- convert_unicode=True is used on the engine
- or String type.
-
- - Fixed memory leak in C version of Decimal result
- processor. [ticket:1978]
-
- - Implemented sequence check capability for the C
- version of RowProxy, as well as 2.7 style
- "collections.Sequence" registration for RowProxy.
- [ticket:1871]
-
- - Threadlocal engine methods rollback(), commit(),
- prepare() won't raise if no transaction is in progress;
- this was a regression introduced in 0.6. [ticket:1998]
-
- - Threadlocal engine returns itself upon begin(),
- begin_nested(); engine then implements contextmanager
- methods to allow the "with" statement. [ticket:2004]
-
-- postgresql
- - Single element tuple expressions inside an IN clause
- parenthesize correctly, also from [ticket:1984]
-
- - Ensured every numeric, float, int code, scalar + array,
- are recognized by psycopg2 and pg8000's "numeric"
- base type. [ticket:1955]
-
- - Added as_uuid=True flag to the UUID type, will receive
- and return values as Python UUID() objects rather than
- strings. Currently, the UUID type is only known to
- work with psycopg2. [ticket:1956]
-
- - Fixed bug whereby KeyError would occur with non-ENUM
- supported PG versions after a pool dispose+recreate
- would occur, [ticket:1989]
-
-- mysql
- - Fixed error handling for Jython + zxjdbc, such that
- has_table() property works again. Regression from
- 0.6.3 (we don't have a Jython buildbot, sorry)
- [ticket:1960]
-
-- sqlite
- - The REFERENCES clause in a CREATE TABLE that includes
- a remote schema to another table with the same schema
- name now renders the remote name without
- the schema clause, as required by SQLite. [ticket:1851]
-
- - On the same theme, the REFERENCES clause in a CREATE TABLE
- that includes a remote schema to a *different* schema
- than that of the parent table doesn't render at all,
- as cross-schema references do not appear to be supported.
-
-- mssql
- - The rewrite of index reflection in [ticket:1770] was
- unfortunately not tested correctly, and returned incorrect
- results. This regression is now fixed.
-
-- oracle
- - The cx_oracle "decimal detection" logic, which takes place
- for for result set columns with ambiguous numeric characteristics,
- now uses the decimal point character determined by the locale/
- NLS_LANG setting, using an on-first-connect detection of
- this character. cx_oracle 5.0.3 or greater is also required
- when using a non-period-decimal-point NLS_LANG setting.
- [ticket:1953].
-
-- firebird
- - Firebird numeric type now checks for Decimal explicitly,
- lets float() pass right through, thereby allowing
- special values such as float('inf'). [ticket:2012]
-
-- declarative
- - An error is raised if __table_args__ is not in tuple
- or dict format, and is not None. [ticket:1972]
-
-- sqlsoup
- - Added "map_to()" method to SqlSoup, which is a "master"
- method which accepts explicit arguments for each aspect of
- the selectable and mapping, including a base class per
- mapping. [ticket:1975]
-
- - Mapped selectables used with the map(), with_labels(),
- join() methods no longer put the given argument into the
- internal "cache" dictionary. Particularly since the
- join() and select() objects are created in the method
- itself this was pretty much a pure memory leaking behavior.
-
-- examples
- - The versioning example now supports detection of changes
- in an associated relationship().
-
-0.6.5
-=====
-- orm
- - Added a new "lazyload" option "immediateload".
- Issues the usual "lazy" load operation automatically
- as the object is populated. The use case
- here is when loading objects to be placed in
- an offline cache, or otherwise used after
- the session isn't available, and straight 'select'
- loading, not 'joined' or 'subquery', is desired.
- [ticket:1914]
-
- - New Query methods: query.label(name), query.as_scalar(),
- return the query's statement as a scalar subquery
- with /without label [ticket:1920];
- query.with_entities(*ent), replaces the SELECT list of
- the query with new entities.
- Roughly equivalent to a generative form of query.values()
- which accepts mapped entities as well as column
- expressions.
-
- - Fixed recursion bug which could occur when moving
- an object from one reference to another, with
- backrefs involved, where the initiating parent
- was a subclass (with its own mapper) of the
- previous parent.
-
- - Fixed a regression in 0.6.4 which occurred if you
- passed an empty list to "include_properties" on
- mapper() [ticket:1918]
-
- - Fixed labeling bug in Query whereby the NamedTuple
- would mis-apply labels if any of the column
- expressions were un-labeled.
-
- - Patched a case where query.join() would adapt the
- right side to the right side of the left's join
- inappropriately [ticket:1925]
-
- - Query.select_from() has been beefed up to help
- ensure that a subsequent call to query.join()
- will use the select_from() entity, assuming it's
- a mapped entity and not a plain selectable,
- as the default "left" side, not the first entity
- in the Query object's list of entities.
-
- - The exception raised by Session when it is used
- subsequent to a subtransaction rollback (which is what
- happens when a flush fails in autocommit=False mode) has
- now been reworded (this is the "inactive due to a
- rollback in a subtransaction" message). In particular,
- if the rollback was due to an exception during flush(),
- the message states this is the case, and reiterates the
- string form of the original exception that occurred
- during flush. If the session is closed due to explicit
- usage of subtransactions (not very common), the message
- just states this is the case.
-
- - The exception raised by Mapper when repeated requests to
- its initialization are made after initialization already
- failed no longer assumes the "hasattr" case, since
- there's other scenarios in which this message gets
- emitted, and the message also does not compound onto
- itself multiple times - you get the same message for
- each attempt at usage. The misnomer "compiles" is being
- traded out for "initialize".
-
- - Fixed bug in query.update() where 'evaluate' or 'fetch'
- expiration would fail if the column expression key was
- a class attribute with a different keyname as the
- actual column name. [ticket:1935]
-
- - Added an assertion during flush which ensures
- that no NULL-holding identity keys were generated
- on "newly persistent" objects.
- This can occur when user defined code inadvertently
- triggers flushes on not-fully-loaded objects.
-
- - lazy loads for relationship attributes now use
- the current state, not the "committed" state,
- of foreign and primary key attributes
- when issuing SQL, if a flush is not in process.
- Previously, only the database-committed state would
- be used. In particular, this would cause a many-to-one
- get()-on-lazyload operation to fail, as autoflush
- is not triggered on these loads when the attributes are
- determined and the "committed" state may not be
- available. [ticket:1910]
-
- - A new flag on relationship(), load_on_pending, allows
- the lazy loader to fire off on pending objects without a
- flush taking place, as well as a transient object that's
- been manually "attached" to the session. Note that this
- flag blocks attribute events from taking place when an
- object is loaded, so backrefs aren't available until
- after a flush. The flag is only intended for very
- specific use cases.
-
- - Another new flag on relationship(), cascade_backrefs,
- disables the "save-update" cascade when the event was
- initiated on the "reverse" side of a bidirectional
- relationship. This is a cleaner behavior so that
- many-to-ones can be set on a transient object without
- it getting sucked into the child object's session,
- while still allowing the forward collection to
- cascade. We *might* default this to False in 0.7.
-
- - Slight improvement to the behavior of
- "passive_updates=False" when placed only on the
- many-to-one side of a relationship; documentation has
- been clarified that passive_updates=False should really
- be on the one-to-many side.
-
- - Placing passive_deletes=True on a many-to-one emits
- a warning, since you probably intended to put it on
- the one-to-many side.
-
- - Fixed bug that would prevent "subqueryload" from
- working correctly with single table inheritance
- for a relationship from a subclass - the "where
- type in (x, y, z)" only gets placed on the inside,
- instead of repeatedly.
-
- - When using from_self() with single table inheritance,
- the "where type in (x, y, z)" is placed on the outside
- of the query only, instead of repeatedly. May make
- some more adjustments to this.
-
- - scoped_session emits a warning when configure() is
- called if a Session is already present (checks only the
- current thread) [ticket:1924]
-
- - reworked the internals of mapper.cascade_iterator() to
- cut down method calls by about 9% in some circumstances.
- [ticket:1932]
-
-- sql
- - Fixed bug in TypeDecorator whereby the dialect-specific
- type was getting pulled in to generate the DDL for a
- given type, which didn't always return the correct result.
-
- - TypeDecorator can now have a fully constructed type
- specified as its "impl", in addition to a type class.
-
- - TypeDecorator will now place itself as the resulting
- type for a binary expression where the type coercion
- rules would normally return its impl type - previously,
- a copy of the impl type would be returned which would
- have the TypeDecorator embedded into it as the "dialect"
- impl, this was probably an unintentional way of achieving
- the desired effect.
-
- - TypeDecorator.load_dialect_impl() returns "self.impl" by
- default, i.e. not the dialect implementation type of
- "self.impl". This to support compilation correctly.
- Behavior can be user-overridden in exactly the same way
- as before to the same effect.
-
- - Added type_coerce(expr, type_) expression element.
- Treats the given expression as the given type when evaluating
- expressions and processing result rows, but does not
- affect the generation of SQL, other than an anonymous
- label.
-
- - Table.tometadata() now copies Index objects associated
- with the Table as well.
-
- - Table.tometadata() issues a warning if the given Table
- is already present in the target MetaData - the existing
- Table object is returned.
-
- - An informative error message is raised if a Column
- which has not yet been assigned a name, i.e. as in
- declarative, is used in a context where it is
- exported to the columns collection of an enclosing
- select() construct, or if any construct involving
- that column is compiled before its name is
- assigned.
-
- - as_scalar(), label() can be called on a selectable
- which contains a Column that is not yet named.
- [ticket:1862]
-
- - Fixed recursion overflow which could occur when operating
- with two expressions both of type "NullType", but
- not the singleton NULLTYPE instance. [ticket:1907]
-
-- declarative
- - @classproperty (soon/now @declared_attr) takes effect for
- __mapper_args__, __table_args__, __tablename__ on
- a base class that is not a mixin, as well as mixins.
- [ticket:1922]
-
- - @classproperty 's official name/location for usage
- with declarative is sqlalchemy.ext.declarative.declared_attr.
- Same thing, but moving there since it is more of a
- "marker" that's specific to declararative,
- not just an attribute technique. [ticket:1915]
-
- - Fixed bug whereby columns on a mixin wouldn't propagate
- correctly to a single-table, or joined-table,
- inheritance scheme where the attribute name is
- different than that of the column. [ticket:1930],
- [ticket:1931].
-
- - A mixin can now specify a column that overrides
- a column of the same name associated with a superclass.
- Thanks to Oystein Haaland.
-
-- engine
-
- - Fixed a regression in 0.6.4 whereby the change that
- allowed cursor errors to be raised consistently broke
- the result.lastrowid accessor. Test coverage has
- been added for result.lastrowid. Note that lastrowid
- is only supported by Pysqlite and some MySQL drivers,
- so isn't super-useful in the general case.
-
- - the logging message emitted by the engine when
- a connection is first used is now "BEGIN (implicit)"
- to emphasize that DBAPI has no explicit begin().
-
- - added "views=True" option to metadata.reflect(),
- will add the list of available views to those
- being reflected. [ticket:1936]
-
- - engine_from_config() now accepts 'debug' for
- 'echo', 'echo_pool', 'force' for 'convert_unicode',
- boolean values for 'use_native_unicode'.
- [ticket:1899]
-
-- postgresql
- - Added "as_tuple" flag to ARRAY type, returns results
- as tuples instead of lists to allow hashing.
-
- - Fixed bug which prevented "domain" built from a
- custom type such as "enum" from being reflected.
- [ticket:1933]
-
-- mysql
- - Fixed bug involving reflection of CURRENT_TIMESTAMP
- default used with ON UPDATE clause, thanks to
- Taavi Burns [ticket:1940]
-
-- oracle
- - The implicit_retunring argument to create_engine()
- is now honored regardless of detected version of
- Oracle. Previously, the flag would be forced
- to False if server version info was < 10.
- [ticket:1878]
-
-- mssql
- - Fixed reflection bug which did not properly handle
- reflection of unknown types. [ticket:1946]
-
- - Fixed bug where aliasing of tables with "schema" would
- fail to compile properly. [ticket:1943]
-
- - Rewrote the reflection of indexes to use sys.
- catalogs, so that column names of any configuration
- (spaces, embedded commas, etc.) can be reflected.
- Note that reflection of indexes requires SQL
- Server 2005 or greater. [ticket:1770]
-
- - mssql+pymssql dialect now honors the "port" portion
- of the URL instead of discarding it. [ticket:1952]
-
-- informix
- - *Major* cleanup / modernization of the Informix
- dialect for 0.6, courtesy Florian Apolloner.
- [ticket:1906]
-
-- tests
- - the NoseSQLAlchemyPlugin has been moved to a
- new package "sqlalchemy_nose" which installs
- along with "sqlalchemy". This so that the "nosetests"
- script works as always but also allows the
- --with-coverage option to turn on coverage before
- SQLAlchemy modules are imported, allowing coverage
- to work correctly.
-
-- misc
- - CircularDependencyError now has .cycles and .edges
- members, which are the set of elements involved in
- one or more cycles, and the set of edges as 2-tuples.
- [ticket:1890]
-
-0.6.4
-=====
-- orm
- - The name ConcurrentModificationError has been
- changed to StaleDataError, and descriptive
- error messages have been revised to reflect
- exactly what the issue is. Both names will
- remain available for the forseeable future
- for schemes that may be specifying
- ConcurrentModificationError in an "except:"
- clause.
-
- - Added a mutex to the identity map which mutexes
- remove operations against iteration methods,
- which now pre-buffer before returning an
- iterable. This because asyncrhonous gc
- can remove items via the gc thread at any time.
- [ticket:1891]
-
- - The Session class is now present in sqlalchemy.orm.*.
- We're moving away from the usage of create_session(),
- which has non-standard defaults, for those situations
- where a one-step Session constructor is desired. Most
- users should stick with sessionmaker() for general use,
- however.
-
- - query.with_parent() now accepts transient objects
- and will use the non-persistent values of their pk/fk
- attributes in order to formulate the criterion.
- Docs are also clarified as to the purpose of with_parent().
-
- - The include_properties and exclude_properties arguments
- to mapper() now accept Column objects as members in
- addition to strings. This so that same-named Column
- objects, such as those within a join(), can be
- disambiguated.
-
- - A warning is now emitted if a mapper is created against a
- join or other single selectable that includes multiple
- columns with the same name in its .c. collection,
- and those columns aren't explictly named as part of
- the same or separate attributes (or excluded).
- In 0.7 this warning will be an exception. Note that
- this warning is not emitted when the combination occurs
- as a result of inheritance, so that attributes
- still allow being overridden naturally.
- [ticket:1896]. In 0.7 this will be improved further.
-
- - The primary_key argument to mapper() can now specify
- a series of columns that are only a subset of
- the calculated "primary key" columns of the mapped
- selectable, without an error being raised. This
- helps for situations where a selectable's effective
- primary key is simpler than the number of columns
- in the selectable that are actually marked as
- "primary_key", such as a join against two
- tables on their primary key columns [ticket:1896].
-
- - An object that's been deleted now gets a flag
- 'deleted', which prohibits the object from
- being re-add()ed to the session, as previously
- the object would live in the identity map
- silently until its attributes were accessed.
- The make_transient() function now resets this
- flag along with the "key" flag.
-
- - make_transient() can be safely called on an
- already transient instance.
-
- - a warning is emitted in mapper() if the polymorphic_on
- column is not present either in direct or derived
- form in the mapped selectable or in the
- with_polymorphic selectable, instead of silently
- ignoring it. Look for this to become an
- exception in 0.7.
-
- - Another pass through the series of error messages
- emitted when relationship() is configured with
- ambiguous arguments. The "foreign_keys"
- setting is no longer mentioned, as it is almost
- never needed and it is preferable users set up
- correct ForeignKey metadata, which is now the
- recommendation. If 'foreign_keys'
- is used and is incorrect, the message suggests
- the attribute is probably unnecessary. Docs
- for the attribute are beefed up. This
- because all confused relationship() users on the
- ML appear to be attempting to use foreign_keys
- due to the message, which only confuses them
- further since Table metadata is much clearer.
-
- - If the "secondary" table has no ForeignKey metadata
- and no foreign_keys is set, even though the
- user is passing screwed up information, it is assumed
- that primary/secondaryjoin expressions should
- consider only and all cols in "secondary" to be
- foreign. It's not possible with "secondary" for
- the foreign keys to be elsewhere in any case.
- A warning is now emitted instead of an error,
- and the mapping succeeds. [ticket:1877]
-
- - Moving an o2m object from one collection to
- another, or vice versa changing the referenced
- object by an m2o, where the foreign key is also a
- member of the primary key, will now be more
- carefully checked during flush if the change in
- value of the foreign key on the "many" side is the
- result of a change in the primary key of the "one"
- side, or if the "one" is just a different object.
- In one case, a cascade-capable DB would have
- cascaded the value already and we need to look at
- the "new" PK value to do an UPDATE, in the other we
- need to continue looking at the "old". We now look
- at the "old", assuming passive_updates=True,
- unless we know it was a PK switch that
- triggered the change. [ticket:1856]
-
- - The value of version_id_col can be changed
- manually, and this will result in an UPDATE
- of the row. Versioned UPDATEs and DELETEs
- now use the "committed" value of the
- version_id_col in the WHERE clause and
- not the pending changed value. The
- version generator is also bypassed if
- manual changes are present on the attribute.
- [ticket:1857]
-
- - Repaired the usage of merge() when used with
- concrete inheriting mappers. Such mappers frequently
- have so-called "concrete" attributes, which are
- subclass attributes that "disable" propagation from
- the parent - these needed to allow a merge()
- operation to pass through without effect.
-
- - Specifying a non-column based argument
- for column_mapped_collection, including string,
- text() etc., will raise an error message that
- specifically asks for a column element, no longer
- misleads with incorrect information about
- text() or literal(). [ticket:1863]
-
- - Similarly, for relationship(), foreign_keys,
- remote_side, order_by - all column-based
- expressions are enforced - lists of strings
- are explicitly disallowed since this is a
- very common error
-
- - Dynamic attributes don't support collection
- population - added an assertion for when
- set_committed_value() is called, as well as
- when joinedload() or subqueryload() options
- are applied to a dynamic attribute, instead
- of failure / silent failure. [ticket:1864]
-
- - Fixed bug whereby generating a Query derived
- from one which had the same column repeated
- with different label names, typically
- in some UNION situations, would fail to
- propagate the inner columns completely to
- the outer query. [ticket:1852]
-
- - object_session() raises the proper
- UnmappedInstanceError when presented with an
- unmapped instance. [ticket:1881]
-
- - Applied further memoizations to calculated Mapper
- properties, with significant (~90%) runtime mapper.py
- call count reduction in heavily polymorphic mapping
- configurations.
-
- - mapper _get_col_to_prop private method used
- by the versioning example is deprecated;
- now use mapper.get_property_by_column() which
- will remain the public method for this.
-
- - the versioning example works correctly now
- if versioning on a col that was formerly
- NULL.
-
-- sql
- - Calling execute() on an alias() construct is pending
- deprecation for 0.7, as it is not itself an
- "executable" construct. It currently "proxies" its
- inner element and is conditionally "executable" but
- this is not the kind of ambiguity we like these days.
-
- - The execute() and scalar() methods of ClauseElement
- are now moved appropriately to the Executable
- subclass. ClauseElement.execute()/ scalar() are still
- present and are pending deprecation in 0.7, but note
- these would always raise an error anyway if you were
- not an Executable (unless you were an alias(), see
- previous note).
-
- - Added basic math expression coercion for
- Numeric->Integer,
- so that resulting type is Numeric regardless
- of the direction of the expression.
-
- - Changed the scheme used to generate truncated
- "auto" index names when using the "index=True"
- flag on Column. The truncation only takes
- place with the auto-generated name, not one
- that is user-defined (an error would be
- raised instead), and the truncation scheme
- itself is now based on a fragment of an md5
- hash of the identifier name, so that multiple
- indexes on columns with similar names still
- have unique names. [ticket:1855]
-
- - The generated index name also is based on
- a "max index name length" attribute which is
- separate from the "max identifier length" -
- this to appease MySQL who has a max length
- of 64 for index names, separate from their
- overall max length of 255. [ticket:1412]
-
- - the text() construct, if placed in a column
- oriented situation, will at least return NULLTYPE
- for its type instead of None, allowing it to
- be used a little more freely for ad-hoc column
- expressions than before. literal_column()
- is still the better choice, however.
-
- - Added full description of parent table/column,
- target table/column in error message raised when
- ForeignKey can't resolve target.
-
- - Fixed bug whereby replacing composite foreign key
- columns in a reflected table would cause an attempt
- to remove the reflected constraint from the table
- a second time, raising a KeyError. [ticket:1865]
-
- - the _Label construct, i.e. the one that is produced
- whenever you say somecol.label(), now counts itself
- in its "proxy_set" unioned with that of it's
- contained column's proxy set, instead of
- directly returning that of the contained column.
- This allows column correspondence
- operations which depend on the identity of the
- _Labels themselves to return the correct result
- - fixes ORM bug [ticket:1852].
-
-- engine
-
- - Calling fetchone() or similar on a result that
- has already been exhausted, has been closed,
- or is not a result-returning result now
- raises ResourceClosedError, a subclass of
- InvalidRequestError, in all cases, regardless
- of backend. Previously, some DBAPIs would
- raise ProgrammingError (i.e. pysqlite), others
- would return None leading to downstream breakages
- (i.e. MySQL-python).
-
- - Fixed bug in Connection whereby if a "disconnect"
- event occurred in the "initialize" phase of the
- first connection pool connect, an AttributeError
- would be raised when the Connection would attempt
- to invalidate the DBAPI connection. [ticket:1894]
-
- - Connection, ResultProxy, as well as Session use
- ResourceClosedError for all "this
- connection/transaction/result is closed" types of
- errors.
-
- - Connection.invalidate() can be called more than
- once and subsequent calls do nothing.
-
-- declarative
- - if @classproperty is used with a regular class-bound
- mapper property attribute, it will be called to get the
- actual attribute value during initialization. Currently,
- there's no advantage to using @classproperty on a column
- or relationship attribute of a declarative class that
- isn't a mixin - evaluation is at the same time as if
- @classproperty weren't used. But here we at least allow
- it to function as expected.
-
- - Fixed bug where "Can't add additional column" message
- would display the wrong name.
-
-- postgresql
- - Fixed the psycopg2 dialect to use its
- set_isolation_level() method instead of relying
- upon the base "SET SESSION ISOLATION" command,
- as psycopg2 resets the isolation level on each new
- transaction otherwise.
-
-- mssql
- - Fixed "default schema" query to work with
- pymssql backend.
-
-- firebird
- - Fixed bug whereby a column default would fail to
- reflect if the "default" keyword were lower case.
-
-- oracle
- - Added ROWID type to the Oracle dialect, for those
- cases where an explicit CAST might be needed.
- [ticket:1879]
-
- - Oracle reflection of indexes has been tuned so
- that indexes which include some or all primary
- key columns, but not the same set of columns
- as that of the primary key, are reflected.
- Indexes which contain the identical columns
- as that of the primary key are skipped within
- reflection, as the index in that case is assumed
- to be the auto-generated primary key index.
- Previously, any index with PK columns present
- would be skipped. Thanks to Kent Bower
- for the patch. [ticket:1867]
-
- - Oracle now reflects the names of primary key
- constraints - also thanks to Kent Bower.
- [ticket:1868]
-
-- informix
- - Applied patches from [ticket:1904] to get
- basic Informix functionality up again. We
- rely upon end-user testing to ensure that
- Informix is working to some degree.
-
-- documentation
- - The docs have been reorganized such that the "API
- Reference" section is gone - all the docstrings from
- there which were public API are moved into the
- context of the main doc section that talks about it.
- Main docs divided into "SQLAlchemy Core" and
- "SQLAlchemy ORM" sections, mapper/relationship docs
- have been broken out. Lots of sections rewritten
- and/or reorganized.
-
-- examples
- - The beaker_caching example has been reorgnized
- such that the Session, cache manager,
- declarative_base are part of environment, and
- custom cache code is portable and now within
- "caching_query.py". This allows the example to
- be easier to "drop in" to existing projects.
-
- - the history_meta versioning recipe sets "unique=False"
- when copying columns, so that the versioning
- table handles multiple rows with repeating values.
- [ticket:1887]
-
-0.6.3
-=====
-- orm
- - Removed errant many-to-many load in unitofwork
- which triggered unnecessarily on expired/unloaded
- collections. This load now takes place only if
- passive_updates is False and the parent primary
- key has changed, or if passive_deletes is False
- and a delete of the parent has occurred.
- [ticket:1845]
-
- - Column-entities (i.e. query(Foo.id)) copy their
- state more fully when queries are derived from
- themselves + a selectable (i.e. from_self(),
- union(), etc.), so that join() and such have the
- correct state to work from. [ticket:1853]
-
- - Fixed bug where Query.join() would fail if
- querying a non-ORM column then joining without
- an on clause when a FROM clause is already
- present, now raises a checked exception the
- same way it does when the clause is not
- present. [ticket:1853]
-
- - Improved the check for an "unmapped class",
- including the case where the superclass is mapped
- but the subclass is not. Any attempts to access
- cls._sa_class_manager.mapper now raise
- UnmappedClassError(). [ticket:1142]
-
- - Added "column_descriptions" accessor to Query,
- returns a list of dictionaries containing
- naming/typing information about the entities
- the Query will return. Can be helpful for
- building GUIs on top of ORM queries.
-
-- mysql
-
- - The _extract_error_code() method now works
- correctly with each MySQL dialect (
- MySQL-python, OurSQL, MySQL-Connector-Python,
- PyODBC). Previously,
- the reconnect logic would fail for OperationalError
- conditions, however since MySQLdb and OurSQL
- have their own reconnect feature, there was no
- symptom for these drivers here unless one
- watched the logs. [ticket:1848]
-
-- oracle
- - More tweaks to cx_oracle Decimal handling.
- "Ambiguous" numerics with no decimal place
- are coerced to int at the connection handler
- level. The advantage here is that ints
- come back as ints without SQLA type
- objects being involved and without needless
- conversion to Decimal first.
-
- Unfortunately, some exotic subquery cases
- can even see different types between
- individual result rows, so the Numeric
- handler, when instructed to return Decimal,
- can't take full advantage of "native decimal"
- mode and must run isinstance() on every value
- to check if its Decimal already. Reopen of
- [ticket:1840]
-
-0.6.2
-=====
-- orm
- - Query.join() will check for a call of the
- form query.join(target, clause_expression),
- i.e. missing the tuple, and raise an informative
- error message that this is the wrong calling form.
-
- - Fixed bug regarding flushes on self-referential
- bi-directional many-to-many relationships, where
- two objects made to mutually reference each other
- in one flush would fail to insert a row for both
- sides. Regression from 0.5. [ticket:1824]
-
- - the post_update feature of relationship() has been
- reworked architecturally to integrate more closely
- with the new 0.6 unit of work. The motivation
- for the change is so that multiple "post update"
- calls, each affecting different foreign key
- columns of the same row, are executed in a single
- UPDATE statement, rather than one UPDATE
- statement per column per row. Multiple row
- updates are also batched into executemany()s as
- possible, while maintaining consistent row ordering.
-
- - Query.statement, Query.subquery(), etc. now transfer
- the values of bind parameters, i.e. those specified
- by query.params(), into the resulting SQL expression.
- Previously the values would not be transferred
- and bind parameters would come out as None.
-
- - Subquery-eager-loading now works with Query objects
- which include params(), as well as get() Queries.
-
- - Can now call make_transient() on an instance that
- is referenced by parent objects via many-to-one,
- without the parent's foreign key value getting
- temporarily set to None - this was a function
- of the "detect primary key switch" flush handler.
- It now ignores objects that are no longer
- in the "persistent" state, and the parent's
- foreign key identifier is left unaffected.
-
- - query.order_by() now accepts False, which cancels
- any existing order_by() state on the Query, allowing
- subsequent generative methods to be called which do
- not support ORDER BY. This is not the same as the
- already existing feature of passing None, which
- suppresses any existing order_by() settings, including
- those configured on the mapper. False will make it
- as though order_by() was never called, while
- None is an active setting.
-
- - An instance which is moved to "transient", has
- an incomplete or missing set of primary key
- attributes, and contains expired attributes, will
- raise an InvalidRequestError if an expired attribute
- is accessed, instead of getting a recursion overflow.
-
- - The make_transient() function is now in the generated
- documentation.
-
- - make_transient() removes all "loader" callables from
- the state being made transient, removing any
- "expired" state - all unloaded attributes reset back
- to undefined, None/empty on access.
-
-- sql
- - The warning emitted by the Unicode and String types
- with convert_unicode=True no longer embeds the actual
- value passed. This so that the Python warning
- registry does not continue to grow in size, the warning
- is emitted once as per the warning filter settings,
- and large string values don't pollute the output.
- [ticket:1822]
-
- - Fixed bug that would prevent overridden clause
- compilation from working for "annotated" expression
- elements, which are often generated by the ORM.
-
- - The argument to "ESCAPE" of a LIKE operator or similar
- is passed through render_literal_value(), which may
- implement escaping of backslashes. [ticket:1400]
-
- - Fixed bug in Enum type which blew away native_enum
- flag when used with TypeDecorators or other adaption
- scenarios.
-
- - Inspector hits bind.connect() when invoked to ensure
- initialize has been called. the internal name ".conn"
- is changed to ".bind", since that's what it is.
-
- - Modified the internals of "column annotation" such that
- a custom Column subclass can safely override
- _constructor to return Column, for the purposes of
- making "configurational" column classes that aren't
- involved in proxying, etc.
-
- - Column.copy() takes along the "unique" attribute
- among others, fixes [ticket:1829] regarding declarative
- mixins
-
-- postgresql
- - render_literal_value() is overridden which escapes
- backslashes, currently applies to the ESCAPE clause
- of LIKE and similar expressions.
- Ultimately this will have to detect the value of
- "standard_conforming_strings" for full behavior.
- [ticket:1400]
-
- - Won't generate "CREATE TYPE" / "DROP TYPE" if
- using types.Enum on a PG version prior to 8.3 -
- the supports_native_enum flag is fully
- honored. [ticket:1836]
-
-- mysql
- - MySQL dialect doesn't emit CAST() for MySQL version
- detected < 4.0.2. This allows the unicode
- check on connect to proceed. [ticket:1826]
-
- - MySQL dialect now detects NO_BACKSLASH_ESCAPES sql
- mode, in addition to ANSI_QUOTES.
-
- - render_literal_value() is overridden which escapes
- backslashes, currently applies to the ESCAPE clause
- of LIKE and similar expressions. This behavior
- is derived from detecting the value of
- NO_BACKSLASH_ESCAPES. [ticket:1400]
-
-- oracle:
- - Fixed ora-8 compatibility flags such that they
- don't cache a stale value from before the first
- database connection actually occurs. [ticket:1819]
-
- - Oracle's "native decimal" metadata begins to return
- ambiguous typing information about numerics
- when columns are embedded in subqueries as well
- as when ROWNUM is consulted with subqueries, as we
- do for limit/offset. We've added these ambiguous
- conditions to the cx_oracle "convert to Decimal()"
- handler, so that we receive numerics as Decimal
- in more cases instead of as floats. These are
- then converted, if requested, into Integer
- or Float, or otherwise kept as the lossless
- Decimal [ticket:1840].
-
-- mssql
- - If server_version_info is outside the usual
- range of (8, ), (9, ), (10, ), a warning is emitted
- which suggests checking that the FreeTDS version
- configuration is using 7.0 or 8.0, not 4.2.
- [ticket:1825]
-
-- firebird
- - Fixed incorrect signature in do_execute(), error
- introduced in 0.6.1. [ticket:1823]
-
- - Firebird dialect adds CHAR, VARCHAR types which
- accept a "charset" flag, to support Firebird
- "CHARACTER SET" clause. [ticket:1813]
-
-- declarative
- - Added support for @classproperty to provide
- any kind of schema/mapping construct from a
- declarative mixin, including columns with foreign
- keys, relationships, column_property, deferred.
- This solves all such issues on declarative mixins.
- An error is raised if any MapperProperty subclass
- is specified on a mixin without using @classproperty.
- [ticket:1751] [ticket:1796] [ticket:1805]
-
- - a mixin class can now define a column that matches
- one which is present on a __table__ defined on a
- subclass. It cannot, however, define one that is
- not present in the __table__, and the error message
- here now works. [ticket:1821]
-
-- compiler extension
- - The 'default' compiler is automatically copied over
- when overriding the compilation of a built in
- clause construct, so no KeyError is raised if the
- user-defined compiler is specific to certain
- backends and compilation for a different backend
- is invoked. [ticket:1838]
-
-- documentation
- - Added documentation for the Inspector. [ticket:1820]
-
- - Fixed @memoized_property and @memoized_instancemethod
- decorators so that Sphinx documentation picks up
- these attributes and methods, such as
- ResultProxy.inserted_primary_key. [ticket:1830]
-
-
-0.6.1
-=====
-- orm
- - Fixed regression introduced in 0.6.0 involving improper
- history accounting on mutable attributes. [ticket:1782]
-
- - Fixed regression introduced in 0.6.0 unit of work refactor
- that broke updates for bi-directional relationship()
- with post_update=True. [ticket:1807]
-
- - session.merge() will not expire attributes on the returned
- instance if that instance is "pending". [ticket:1789]
-
- - fixed __setstate__ method of CollectionAdapter to not
- fail during deserialize where parent InstanceState not
- yet unserialized. [ticket:1802]
-
- - Added internal warning in case an instance without a
- full PK happened to be expired and then was asked
- to refresh. [ticket:1797]
-
- - Added more aggressive caching to the mapper's usage of
- UPDATE, INSERT, and DELETE expressions. Assuming the
- statement has no per-object SQL expressions attached,
- the expression objects are cached by the mapper after
- the first create, and their compiled form is stored
- persistently in a cache dictionary for the duration of
- the related Engine. The cache is an LRUCache for the
- rare case that a mapper receives an extremely
- high number of different column patterns as UPDATEs.
-
-- sql
- - expr.in_() now accepts a text() construct as the argument.
- Grouping parenthesis are added automatically, i.e. usage
- is like `col.in_(text("select id from table"))`.
- [ticket:1793]
-
- - Columns of _Binary type (i.e. LargeBinary, BLOB, etc.)
- will coerce a "basestring" on the right side into a
- _Binary as well so that required DBAPI processing
- takes place.
-
- - Added table.add_is_dependent_on(othertable), allows manual
- placement of dependency rules between two Table objects
- for use within create_all(), drop_all(), sorted_tables.
- [ticket:1801]
-
- - Fixed bug that prevented implicit RETURNING from functioning
- properly with composite primary key that contained zeroes.
- [ticket:1778]
-
- - Fixed errant space character when generating ADD CONSTRAINT
- for a named UNIQUE constraint.
-
- - Fixed "table" argument on constructor of ForeginKeyConstraint
- [ticket:1571]
-
- - Fixed bug in connection pool cursor wrapper whereby if a
- cursor threw an exception on close(), the logging of the
- message would fail. [ticket:1786]
-
- - the _make_proxy() method of ColumnClause and Column now use
- self.__class__ to determine the class of object to be returned
- instead of hardcoding to ColumnClause/Column, making it slightly
- easier to produce specific subclasses of these which work in
- alias/subquery situations.
-
- - func.XXX() doesn't inadvertently resolve to non-Function
- classes (e.g. fixes func.text()). [ticket:1798]
-
-- engines
- - Fixed building the C extensions on Python 2.4. [ticket:1781]
-
- - Pool classes will reuse the same "pool_logging_name" setting
- after a dispose() occurs.
-
- - Engine gains an "execution_options" argument and
- update_execution_options() method, which will apply to
- all connections generated by this engine.
-
-- mysql
- - func.sysdate() emits "SYSDATE()", i.e. with the ending
- parenthesis, on MySQL. [ticket:1794]
-
-- sqlite
- - Fixed concatenation of constraints when "PRIMARY KEY"
- constraint gets moved to column level due to SQLite
- AUTOINCREMENT keyword being rendered. [ticket:1812]
-
-- oracle
- - Added a check for cx_oracle versions lower than version 5,
- in which case the incompatible "output type handler" won't
- be used. This will impact decimal accuracy and some
- unicode handling issues. [ticket:1775]
-
- - Fixed use_ansi=False mode, which was producing broken
- WHERE clauses in pretty much all cases. [ticket:1790]
-
- - Re-established support for Oracle 8 with cx_oracle,
- including that use_ansi is set to False automatically,
- NVARCHAR2 and NCLOB are not rendered for Unicode,
- "native unicode" check doesn't fail, cx_oracle
- "native unicode" mode is disabled, VARCHAR() is emitted
- with bytes count instead of char count. [ticket:1808]
-
- - oracle_xe 5 doesn't accept a Python unicode object in
- its connect string in normal Python 2.x mode - so we coerce
- to str() directly. non-ascii characters aren't supported
- in connect strings here since we don't know what encoding
- we could use. [ticket:1670]
-
- - FOR UPDATE is emitted in the syntactically correct position
- when limit/offset is used, i.e. the ROWNUM subquery.
- However, Oracle can't really handle FOR UPDATE with ORDER BY
- or with subqueries, so its still not very usable, but at
- least SQLA gets the SQL past the Oracle parser.
- [ticket:1815]
-
-- firebird
- - Added a label to the query used within has_table() and
- has_sequence() to work with older versions of Firebird
- that don't provide labels for result columns. [ticket:1521]
-
- - Added integer coercion to the "type_conv" attribute when
- passed via query string, so that it is properly interpreted
- by Kinterbasdb. [ticket:1779]
-
- - Added 'connection shutdown' to the list of exception strings
- which indicate a dropped connection. [ticket:1646]
-
-- sqlsoup
- - the SqlSoup constructor accepts a `base` argument which specifies
- the base class to use for mapped classes, the default being
- `object`. [ticket:1783]
-
-0.6.0
-=====
-
-- orm
- - Unit of work internals have been rewritten. Units of work
- with large numbers of objects interdependent objects
- can now be flushed without recursion overflows
- as there is no longer reliance upon recursive calls
- [ticket:1081]. The number of internal structures now stays
- constant for a particular session state, regardless of
- how many relationships are present on mappings. The flow
- of events now corresponds to a linear list of steps,
- generated by the mappers and relationships based on actual
- work to be done, filtered through a single topological sort
- for correct ordering. Flush actions are assembled using
- far fewer steps and less memory. [ticket:1742]
-
- - Along with the UOW rewrite, this also removes an issue
- introduced in 0.6beta3 regarding topological cycle detection
- for units of work with long dependency cycles. We now use
- an algorithm written by Guido (thanks Guido!).
-
- - one-to-many relationships now maintain a list of positive
- parent-child associations within the flush, preventing
- previous parents marked as deleted from cascading a
- delete or NULL foreign key set on those child objects,
- despite the end-user not removing the child from the old
- association. [ticket:1764]
-
- - A collection lazy load will switch off default
- eagerloading on the reverse many-to-one side, since
- that loading is by definition unnecessary. [ticket:1495]
-
- - Session.refresh() now does an equivalent expire()
- on the given instance first, so that the "refresh-expire"
- cascade is propagated. Previously, refresh() was
- not affected in any way by the presence of "refresh-expire"
- cascade. This is a change in behavior versus that
- of 0.6beta2, where the "lockmode" flag passed to refresh()
- would cause a version check to occur. Since the instance
- is first expired, refresh() always upgrades the object
- to the most recent version.
-
- - The 'refresh-expire' cascade, when reaching a pending object,
- will expunge the object if the cascade also includes
- "delete-orphan", or will simply detach it otherwise.
- [ticket:1754]
-
- - id(obj) is no longer used internally within topological.py,
- as the sorting functions now require hashable objects
- only. [ticket:1756]
-
- - The ORM will set the docstring of all generated descriptors
- to None by default. This can be overridden using 'doc'
- (or if using Sphinx, attribute docstrings work too).
-
- - Added kw argument 'doc' to all mapper property callables
- as well as Column(). Will assemble the string 'doc' as
- the '__doc__' attribute on the descriptor.
-
- - Usage of version_id_col on a backend that supports
- cursor.rowcount for execute() but not executemany() now works
- when a delete is issued (already worked for saves, since those
- don't use executemany()). For a backend that doesn't support
- cursor.rowcount at all, a warning is emitted the same
- as with saves. [ticket:1761]
-
- - The ORM now short-term caches the "compiled" form of
- insert() and update() constructs when flushing lists of
- objects of all the same class, thereby avoiding redundant
- compilation per individual INSERT/UPDATE within an
- individual flush() call.
-
- - internal getattr(), setattr(), getcommitted() methods
- on ColumnProperty, CompositeProperty, RelationshipProperty
- have been underscored (i.e. are private), signature has
- changed.
-
-- engines
- - The C extension now also works with DBAPIs which use custom
- sequences as row (and not only tuples). [ticket:1757]
-
-- sql
- - Restored some bind-labeling logic from 0.5 which ensures
- that tables with column names that overlap another column
- of the form "<tablename>_<columnname>" won't produce
- errors if column._label is used as a bind name during
- an UPDATE. Test coverage which wasn't present in 0.5
- has been added. [ticket:1755]
-
- - somejoin.select(fold_equivalents=True) is no longer
- deprecated, and will eventually be rolled into a more
- comprehensive version of the feature for [ticket:1729].
-
- - the Numeric type raises an *enormous* warning when expected
- to convert floats to Decimal from a DBAPI that returns floats.
- This includes SQLite, Sybase, MS-SQL. [ticket:1759]
-
- - Fixed an error in expression typing which caused an endless
- loop for expressions with two NULL types.
-
- - Fixed bug in execution_options() feature whereby the existing
- Transaction and other state information from the parent
- connection would not be propagated to the sub-connection.
-
- - Added new 'compiled_cache' execution option. A dictionary
- where Compiled objects will be cached when the Connection
- compiles a clause expression into a dialect- and parameter-
- specific Compiled object. It is the user's responsibility to
- manage the size of this dictionary, which will have keys
- corresponding to the dialect, clause element, the column
- names within the VALUES or SET clause of an INSERT or UPDATE,
- as well as the "batch" mode for an INSERT or UPDATE statement.
-
- - Added get_pk_constraint() to reflection.Inspector, similar
- to get_primary_keys() except returns a dict that includes the
- name of the constraint, for supported backends (PG so far).
- [ticket:1769]
-
- - Table.create() and Table.drop() no longer apply metadata-
- level create/drop events. [ticket:1771]
-
-- ext
- - the compiler extension now allows @compiles decorators
- on base classes that extend to child classes, @compiles
- decorators on child classes that aren't broken by a
- @compiles decorator on the base class.
-
- - Declarative will raise an informative error message
- if a non-mapped class attribute is referenced in the
- string-based relationship() arguments.
-
- - Further reworked the "mixin" logic in declarative to
- additionally allow __mapper_args__ as a @classproperty
- on a mixin, such as to dynamically assign polymorphic_identity.
-
-- postgresql
- - Postgresql now reflects sequence names associated with
- SERIAL columns correctly, after the name of of the sequence
- has been changed. Thanks to Kumar McMillan for the patch.
- [ticket:1071]
-
- - Repaired missing import in psycopg2._PGNumeric type when
- unknown numeric is received.
-
- - psycopg2/pg8000 dialects now aware of REAL[], FLOAT[],
- DOUBLE_PRECISION[], NUMERIC[] return types without
- raising an exception.
-
- - Postgresql reflects the name of primary key constraints,
- if one exists. [ticket:1769]
-
-- oracle
- - Now using cx_oracle output converters so that the
- DBAPI returns natively the kinds of values we prefer:
- - NUMBER values with positive precision + scale convert
- to cx_oracle.STRING and then to Decimal. This
- allows perfect precision for the Numeric type when
- using cx_oracle. [ticket:1759]
- - STRING/FIXED_CHAR now convert to unicode natively.
- SQLAlchemy's String types then don't need to
- apply any kind of conversions.
-
-- firebird
- - The functionality of result.rowcount can be disabled on a
- per-engine basis by setting 'enable_rowcount=False'
- on create_engine(). Normally, cursor.rowcount is called
- after any UPDATE or DELETE statement unconditionally,
- because the cursor is then closed and Firebird requires
- an open cursor in order to get a rowcount. This
- call is slightly expensive however so it can be disabled.
- To re-enable on a per-execution basis, the
- 'enable_rowcount=True' execution option may be used.
-
-- examples
- - Updated attribute_shard.py example to use a more robust
- method of searching a Query for binary expressions which
- compare columns against literal values.
-
-0.6beta3
-========
-
-- orm
- - Major feature: Added new "subquery" loading capability to
- relationship(). This is an eager loading option which
- generates a second SELECT for each collection represented
- in a query, across all parents at once. The query
- re-issues the original end-user query wrapped in a subquery,
- applies joins out to the target collection, and loads
- all those collections fully in one result, similar to
- "joined" eager loading but using all inner joins and not
- re-fetching full parent rows repeatedly (as most DBAPIs seem
- to do, even if columns are skipped). Subquery loading is
- available at mapper config level using "lazy='subquery'" and
- at the query options level using "subqueryload(props..)",
- "subqueryload_all(props...)". [ticket:1675]
-
- - To accomodate the fact that there are now two kinds of eager
- loading available, the new names for eagerload() and
- eagerload_all() are joinedload() and joinedload_all(). The
- old names will remain as synonyms for the foreseeable future.
-
- - The "lazy" flag on the relationship() function now accepts
- a string argument for all kinds of loading: "select", "joined",
- "subquery", "noload" and "dynamic", where the default is now
- "select". The old values of True/
- False/None still retain their usual meanings and will remain
- as synonyms for the foreseeable future.
-
- - Added with_hint() method to Query() construct. This calls
- directly down to select().with_hint() and also accepts
- entities as well as tables and aliases. See with_hint() in the
- SQL section below. [ticket:921]
-
- - Fixed bug in Query whereby calling q.join(prop).from_self(...).
- join(prop) would fail to render the second join outside the
- subquery, when joining on the same criterion as was on the
- inside.
-
- - Fixed bug in Query whereby the usage of aliased() constructs
- would fail if the underlying table (but not the actual alias)
- were referenced inside the subquery generated by
- q.from_self() or q.select_from().
-
- - Fixed bug which affected all eagerload() and similar options
- such that "remote" eager loads, i.e. eagerloads off of a lazy
- load such as query(A).options(eagerload(A.b, B.c))
- wouldn't eagerload anything, but using eagerload("b.c") would
- work fine.
-
- - Query gains an add_columns(*columns) method which is a multi-
- version of add_column(col). add_column(col) is future
- deprecated.
-
- - Query.join() will detect if the end result will be
- "FROM A JOIN A", and will raise an error if so.
-
- - Query.join(Cls.propname, from_joinpoint=True) will check more
- carefully that "Cls" is compatible with the current joinpoint,
- and act the same way as Query.join("propname", from_joinpoint=True)
- in that regard.
-
-- sql
- - Added with_hint() method to select() construct. Specify
- a table/alias, hint text, and optional dialect name, and
- "hints" will be rendered in the appropriate place in the
- statement. Works for Oracle, Sybase, MySQL. [ticket:921]
-
- - Fixed bug introduced in 0.6beta2 where column labels would
- render inside of column expressions already assigned a label.
- [ticket:1747]
-
-- postgresql
- - The psycopg2 dialect will log NOTICE messages via the
- "sqlalchemy.dialects.postgresql" logger name.
- [ticket:877]
-
- - the TIME and TIMESTAMP types are now availble from the
- postgresql dialect directly, which add the PG-specific
- argument 'precision' to both. 'precision' and
- 'timezone' are correctly reflected for both TIME and
- TIMEZONE types. [ticket:997]
-
-- mysql
- - No longer guessing that TINYINT(1) should be BOOLEAN
- when reflecting - TINYINT(1) is returned. Use Boolean/
- BOOLEAN in table definition to get boolean conversion
- behavior. [ticket:1752]
-
-- oracle
- - The Oracle dialect will issue VARCHAR type definitions
- using character counts, i.e. VARCHAR2(50 CHAR), so that
- the column is sized in terms of characters and not bytes.
- Column reflection of character types will also use
- ALL_TAB_COLUMNS.CHAR_LENGTH instead of
- ALL_TAB_COLUMNS.DATA_LENGTH. Both of these behaviors take
- effect when the server version is 9 or higher - for
- version 8, the old behaviors are used. [ticket:1744]
-
-- declarative
- - Using a mixin won't break if the mixin implements an
- unpredictable __getattribute__(), i.e. Zope interfaces.
- [ticket:1746]
-
- - Using @classdecorator and similar on mixins to define
- __tablename__, __table_args__, etc. now works if
- the method references attributes on the ultimate
- subclass. [ticket:1749]
-
- - relationships and columns with foreign keys aren't
- allowed on declarative mixins, sorry. [ticket:1751]
-
-- ext
- - The sqlalchemy.orm.shard module now becomes an extension,
- sqlalchemy.ext.horizontal_shard. The old import
- works with a deprecation warning.
-
-0.6beta2
-========
-
-- py3k
- - Improved the installation/test setup regarding Python 3,
- now that Distribute runs on Py3k. distribute_setup.py
- is now included. See README.py3k for Python 3 installation/
- testing instructions.
-
-- orm
- - The official name for the relation() function is now
- relationship(), to eliminate confusion over the relational
- algebra term. relation() however will remain available
- in equal capacity for the foreseeable future. [ticket:1740]
-
- - Added "version_id_generator" argument to Mapper, this is a
- callable that, given the current value of the "version_id_col",
- returns the next version number. Can be used for alternate
- versioning schemes such as uuid, timestamps. [ticket:1692]
-
- - added "lockmode" kw argument to Session.refresh(), will
- pass through the string value to Query the same as
- in with_lockmode(), will also do version check for a
- version_id_col-enabled mapping.
-
- - Fixed bug whereby calling query(A).join(A.bs).add_entity(B)
- in a joined inheritance scenario would double-add B as a
- target and produce an invalid query. [ticket:1188]
-
- - Fixed bug in session.rollback() which involved not removing
- formerly "pending" objects from the session before
- re-integrating "deleted" objects, typically occured with
- natural primary keys. If there was a primary key conflict
- between them, the attach of the deleted would fail
- internally. The formerly "pending" objects are now expunged
- first. [ticket:1674]
-
- - Removed a lot of logging that nobody really cares about,
- logging that remains will respond to live changes in the
- log level. No significant overhead is added. [ticket:1719]
-
- - Fixed bug in session.merge() which prevented dict-like
- collections from merging.
-
- - session.merge() works with relations that specifically
- don't include "merge" in their cascade options - the target
- is ignored completely.
-
- - session.merge() will not expire existing scalar attributes
- on an existing target if the target has a value for that
- attribute, even if the incoming merged doesn't have
- a value for the attribute. This prevents unnecessary loads
- on existing items. Will still mark the attr as expired
- if the destination doesn't have the attr, though, which
- fulfills some contracts of deferred cols. [ticket:1681]
-
- - The "allow_null_pks" flag is now called "allow_partial_pks",
- defaults to True, acts like it did in 0.5 again. Except,
- it also is implemented within merge() such that a SELECT
- won't be issued for an incoming instance with partially
- NULL primary key if the flag is False. [ticket:1680]
-
- - Fixed bug in 0.6-reworked "many-to-one" optimizations
- such that a many-to-one that is against a non-primary key
- column on the remote table (i.e. foreign key against a
- UNIQUE column) will pull the "old" value in from the
- database during a change, since if it's in the session
- we will need it for proper history/backref accounting,
- and we can't pull from the local identity map on a
- non-primary key column. [ticket:1737]
-
- - fixed internal error which would occur if calling has()
- or similar complex expression on a single-table inheritance
- relation(). [ticket:1731]
-
- - query.one() no longer applies LIMIT to the query, this to
- ensure that it fully counts all object identities present
- in the result, even in the case where joins may conceal
- multiple identities for two or more rows. As a bonus,
- one() can now also be called with a query that issued
- from_statement() to start with since it no longer modifies
- the query. [ticket:1688]
-
- - query.get() now returns None if queried for an identifier
- that is present in the identity map with a different class
- than the one requested, i.e. when using polymorphic loading.
- [ticket:1727]
-
- - A major fix in query.join(), when the "on" clause is an
- attribute of an aliased() construct, but there is already
- an existing join made out to a compatible target, query properly
- joins to the right aliased() construct instead of sticking
- onto the right side of the existing join. [ticket:1706]
-
- - Slight improvement to the fix for [ticket:1362] to not issue
- needless updates of the primary key column during a so-called
- "row switch" operation, i.e. add + delete of two objects
- with the same PK.
-
- - Now uses sqlalchemy.orm.exc.DetachedInstanceError when an
- attribute load or refresh action fails due to object
- being detached from any Session. UnboundExecutionError
- is specific to engines bound to sessions and statements.
-
- - Query called in the context of an expression will render
- disambiguating labels in all cases. Note that this does
- not apply to the existing .statement and .subquery()
- accessor/method, which still honors the .with_labels()
- setting that defaults to False.
-
- - Query.union() retains disambiguating labels within the
- returned statement, thus avoiding various SQL composition
- errors which can result from column name conflicts.
- [ticket:1676]
-
- - Fixed bug in attribute history that inadvertently invoked
- __eq__ on mapped instances.
-
- - Some internal streamlining of object loading grants a
- small speedup for large results, estimates are around
- 10-15%. Gave the "state" internals a good solid
- cleanup with less complexity, datamembers,
- method calls, blank dictionary creates.
-
- - Documentation clarification for query.delete()
- [ticket:1689]
-
- - Fixed cascade bug in many-to-one relation() when attribute
- was set to None, introduced in r6711 (cascade deleted
- items into session during add()).
-
- - Calling query.order_by() or query.distinct() before calling
- query.select_from(), query.with_polymorphic(), or
- query.from_statement() raises an exception now instead of
- silently dropping those criterion. [ticket:1736]
-
- - query.scalar() now raises an exception if more than one
- row is returned. All other behavior remains the same.
- [ticket:1735]
-
- - Fixed bug which caused "row switch" logic, that is an
- INSERT and DELETE replaced by an UPDATE, to fail when
- version_id_col was in use. [ticket:1692]
-
-- sql
- - join() will now simulate a NATURAL JOIN by default. Meaning,
- if the left side is a join, it will attempt to join the right
- side to the rightmost side of the left first, and not raise
- any exceptions about ambiguous join conditions if successful
- even if there are further join targets across the rest of
- the left. [ticket:1714]
-
- - The most common result processors conversion function were
- moved to the new "processors" module. Dialect authors are
- encouraged to use those functions whenever they correspond
- to their needs instead of implementing custom ones.
-
- - SchemaType and subclasses Boolean, Enum are now serializable,
- including their ddl listener and other event callables.
- [ticket:1694] [ticket:1698]
-
- - Some platforms will now interpret certain literal values
- as non-bind parameters, rendered literally into the SQL
- statement. This to support strict SQL-92 rules that are
- enforced by some platforms including MS-SQL and Sybase.
- In this model, bind parameters aren't allowed in the
- columns clause of a SELECT, nor are certain ambiguous
- expressions like "?=?". When this mode is enabled, the base
- compiler will render the binds as inline literals, but only across
- strings and numeric values. Other types such as dates
- will raise an error, unless the dialect subclass defines
- a literal rendering function for those. The bind parameter
- must have an embedded literal value already or an error
- is raised (i.e. won't work with straight bindparam('x')).
- Dialects can also expand upon the areas where binds are not
- accepted, such as within argument lists of functions
- (which don't work on MS-SQL when native SQL binding is used).
-
- - Added "unicode_errors" parameter to String, Unicode, etc.
- Behaves like the 'errors' keyword argument to
- the standard library's string.decode() functions. This flag
- requires that `convert_unicode` is set to `"force"` - otherwise,
- SQLAlchemy is not guaranteed to handle the task of unicode
- conversion. Note that this flag adds significant performance
- overhead to row-fetching operations for backends that already
- return unicode objects natively (which most DBAPIs do). This
- flag should only be used as an absolute last resort for reading
- strings from a column with varied or corrupted encodings,
- which only applies to databases that accept invalid encodings
- in the first place (i.e. MySQL. *not* PG, Sqlite, etc.)
-
- - Added math negation operator support, -x.
-
- - FunctionElement subclasses are now directly executable the
- same way any func.foo() construct is, with automatic
- SELECT being applied when passed to execute().
-
- - The "type" and "bind" keyword arguments of a func.foo()
- construct are now local to "func." constructs and are
- not part of the FunctionElement base class, allowing
- a "type" to be handled in a custom constructor or
- class-level variable.
-
- - Restored the keys() method to ResultProxy.
-
- - The type/expression system now does a more complete job
- of determining the return type from an expression
- as well as the adaptation of the Python operator into
- a SQL operator, based on the full left/right/operator
- of the given expression. In particular
- the date/time/interval system created for Postgresql
- EXTRACT in [ticket:1647] has now been generalized into
- the type system. The previous behavior which often
- occured of an expression "column + literal" forcing
- the type of "literal" to be the same as that of "column"
- will now usually not occur - the type of
- "literal" is first derived from the Python type of the
- literal, assuming standard native Python types + date
- types, before falling back to that of the known type
- on the other side of the expression. If the
- "fallback" type is compatible (i.e. CHAR from String),
- the literal side will use that. TypeDecorator
- types override this by default to coerce the "literal"
- side unconditionally, which can be changed by implementing
- the coerce_compared_value() method. Also part of
- [ticket:1683].
-
- - Made sqlalchemy.sql.expressions.Executable part of public
- API, used for any expression construct that can be sent to
- execute(). FunctionElement now inherits Executable so that
- it gains execution_options(), which are also propagated
- to the select() that's generated within execute().
- Executable in turn subclasses _Generative which marks
- any ClauseElement that supports the @_generative
- decorator - these may also become "public" for the benefit
- of the compiler extension at some point.
-
- - A change to the solution for [ticket:1579] - an end-user
- defined bind parameter name that directly conflicts with
- a column-named bind generated directly from the SET or
- VALUES clause of an update/insert generates a compile error.
- This reduces call counts and eliminates some cases where
- undesirable name conflicts could still occur.
-
- - Column() requires a type if it has no foreign keys (this is
- not new). An error is now raised if a Column() has no type
- and no foreign keys. [ticket:1705]
-
- - the "scale" argument of the Numeric() type is honored when
- coercing a returned floating point value into a string
- on its way to Decimal - this allows accuracy to function
- on SQLite, MySQL. [ticket:1717]
-
- - the copy() method of Column now copies over uninitialized
- "on table attach" events. Helps with the new declarative
- "mixin" capability.
-
-- engines
- - Added an optional C extension to speed up the sql layer by
- reimplementing RowProxy and the most common result processors.
- The actual speedups will depend heavily on your DBAPI and
- the mix of datatypes used in your tables, and can vary from
- a 30% improvement to more than 200%. It also provides a modest
- (~15-20%) indirect improvement to ORM speed for large queries.
- Note that it is *not* built/installed by default.
- See README for installation instructions.
-
- - the execution sequence pulls all rowcount/last inserted ID
- info from the cursor before commit() is called on the
- DBAPI connection in an "autocommit" scenario. This helps
- mxodbc with rowcount and is probably a good idea overall.
-
- - Opened up logging a bit such that isEnabledFor() is called
- more often, so that changes to the log level for engine/pool
- will be reflected on next connect. This adds a small
- amount of method call overhead. It's negligible and will make
- life a lot easier for all those situations when logging
- just happens to be configured after create_engine() is called.
- [ticket:1719]
-
- - The assert_unicode flag is deprecated. SQLAlchemy will raise
- a warning in all cases where it is asked to encode a non-unicode
- Python string, as well as when a Unicode or UnicodeType type
- is explicitly passed a bytestring. The String type will do nothing
- for DBAPIs that already accept Python unicode objects.
-
- - Bind parameters are sent as a tuple instead of a list. Some
- backend drivers will not accept bind parameters as a list.
-
- - threadlocal engine wasn't properly closing the connection
- upon close() - fixed that.
-
- - Transaction object doesn't rollback or commit if it isn't
- "active", allows more accurate nesting of begin/rollback/commit.
-
- - Python unicode objects as binds result in the Unicode type,
- not string, thus eliminating a certain class of unicode errors
- on drivers that don't support unicode binds.
-
- - Added "logging_name" argument to create_engine(), Pool() constructor
- as well as "pool_logging_name" argument to create_engine() which
- filters down to that of Pool. Issues the given string name
- within the "name" field of logging messages instead of the default
- hex identifier string. [ticket:1555]
-
- - The visit_pool() method of Dialect is removed, and replaced with
- connect(). This method returns a callable which receives
- the raw DBAPI connection after each one is created. The callable
- is assembled into a first_connect/connect pool listener by the
- connection strategy if non-None. Provides a simpler interface
- for dialects.
-
- - StaticPool now initializes, disposes and recreates without
- opening a new connection - the connection is only opened when
- first requested. dispose() also works on AssertionPool now.
- [ticket:1728]
-
-- metadata
- - Added the ability to strip schema information when using
- "tometadata" by passing "schema=None" as an argument. If schema
- is not specified then the table's schema is retained.
- [ticket: 1673]
-
-- declarative
- - DeclarativeMeta exclusively uses cls.__dict__ (not dict_)
- as the source of class information; _as_declarative exclusively
- uses the dict_ passed to it as the source of class information
- (which when using DeclarativeMeta is cls.__dict__). This should
- in theory make it easier for custom metaclasses to modify
- the state passed into _as_declarative.
-
- - declarative now accepts mixin classes directly, as a means
- to provide common functional and column-based elements on
- all subclasses, as well as a means to propagate a fixed
- set of __table_args__ or __mapper_args__ to subclasses.
- For custom combinations of __table_args__/__mapper_args__ from
- an inherited mixin to local, descriptors can now be used.
- New details are all up in the Declarative documentation.
- Thanks to Chris Withers for putting up with my strife
- on this. [ticket:1707]
-
- - the __mapper_args__ dict is copied when propagating to a subclass,
- and is taken straight off the class __dict__ to avoid any
- propagation from the parent. mapper inheritance already
- propagates the things you want from the parent mapper.
- [ticket:1393]
-
- - An exception is raised when a single-table subclass specifies
- a column that is already present on the base class.
- [ticket:1732]
-
-- mysql
- - Fixed reflection bug whereby when COLLATE was present,
- nullable flag and server defaults would not be reflected.
- [ticket:1655]
-
- - Fixed reflection of TINYINT(1) "boolean" columns defined with
- integer flags like UNSIGNED.
-
- - Further fixes for the mysql-connector dialect. [ticket:1668]
-
- - Composite PK table on InnoDB where the "autoincrement" column
- isn't first will emit an explicit "KEY" phrase within
- CREATE TABLE thereby avoiding errors, [ticket:1496]
-
- - Added reflection/create table support for a wide range
- of MySQL keywords. [ticket:1634]
-
- - Fixed import error which could occur reflecting tables on
- a Windows host [ticket:1580]
-
-- mssql
- - Re-established support for the pymssql dialect.
-
- - Various fixes for implicit returning, reflection,
- etc. - the MS-SQL dialects aren't quite complete
- in 0.6 yet (but are close)
-
- - Added basic support for mxODBC [ticket:1710].
-
- - Removed the text_as_varchar option.
-
-- oracle
- - "out" parameters require a type that is supported by
- cx_oracle. An error will be raised if no cx_oracle
- type can be found.
-
- - Oracle 'DATE' now does not perform any result processing,
- as the DATE type in Oracle stores full date+time objects,
- that's what you'll get. Note that the generic types.Date
- type *will* still call value.date() on incoming values,
- however. When reflecting a table, the reflected type
- will be 'DATE'.
-
- - Added preliminary support for Oracle's WITH_UNICODE
- mode. At the very least this establishes initial
- support for cx_Oracle with Python 3. When WITH_UNICODE
- mode is used in Python 2.xx, a large and scary warning
- is emitted asking that the user seriously consider
- the usage of this difficult mode of operation.
- [ticket:1670]
-
- - The except_() method now renders as MINUS on Oracle,
- which is more or less equivalent on that platform.
- [ticket:1712]
-
- - Added support for rendering and reflecting
- TIMESTAMP WITH TIME ZONE, i.e. TIMESTAMP(timezone=True).
- [ticket:651]
-
- - Oracle INTERVAL type can now be reflected.
-
-- sqlite
- - Added "native_datetime=True" flag to create_engine().
- This will cause the DATE and TIMESTAMP types to skip
- all bind parameter and result row processing, under
- the assumption that PARSE_DECLTYPES has been enabled
- on the connection. Note that this is not entirely
- compatible with the "func.current_date()", which
- will be returned as a string. [ticket:1685]
-
-- sybase
- - Implemented a preliminary working dialect for Sybase,
- with sub-implementations for Python-Sybase as well
- as Pyodbc. Handles table
- creates/drops and basic round trip functionality.
- Does not yet include reflection or comprehensive
- support of unicode/special expressions/etc.
-
-- examples
- - Changed the beaker cache example a bit to have a separate
- RelationCache option for lazyload caching. This object
- does a lookup among any number of potential attributes
- more efficiently by grouping several into a common structure.
- Both FromCache and RelationCache are simpler individually.
-
-- documentation
- - Major cleanup work in the docs to link class, function, and
- method names into the API docs. [ticket:1700/1702/1703]
-
-0.6beta1
-========
-- Major Release
- - For the full set of feature descriptions, see
- http://www.sqlalchemy.org/trac/wiki/06Migration .
- This document is a work in progress.
-
- - All bug fixes and feature enhancements from the most
- recent 0.5 version and below are also included within 0.6.
-
- - Platforms targeted now include Python 2.4/2.5/2.6, Python
- 3.1, Jython2.5.
-
-- orm
- - Changes to query.update() and query.delete():
- - the 'expire' option on query.update() has been renamed to
- 'fetch', thus matching that of query.delete().
- 'expire' is deprecated and issues a warning.
-
- - query.update() and query.delete() both default to
- 'evaluate' for the synchronize strategy.
-
- - the 'synchronize' strategy for update() and delete()
- raises an error on failure. There is no implicit fallback
- onto "fetch". Failure of evaluation is based on the
- structure of criteria, so success/failure is deterministic
- based on code structure.
-
- - Enhancements on many-to-one relations:
- - many-to-one relations now fire off a lazyload in fewer
- cases, including in most cases will not fetch the "old"
- value when a new one is replaced.
-
- - many-to-one relation to a joined-table subclass now uses
- get() for a simple load (known as the "use_get"
- condition), i.e. Related->Sub(Base), without the need to
- redefine the primaryjoin condition in terms of the base
- table. [ticket:1186]
-
- - specifying a foreign key with a declarative column, i.e.
- ForeignKey(MyRelatedClass.id) doesn't break the "use_get"
- condition from taking place [ticket:1492]
-
- - relation(), eagerload(), and eagerload_all() now feature
- an option called "innerjoin". Specify `True` or `False` to
- control whether an eager join is constructed as an INNER
- or OUTER join. Default is `False` as always. The mapper
- options will override whichever setting is specified on
- relation(). Should generally be set for many-to-one, not
- nullable foreign key relations to allow improved join
- performance. [ticket:1544]
-
- - the behavior of eagerloading such that the main query is
- wrapped in a subquery when LIMIT/OFFSET are present now
- makes an exception for the case when all eager loads are
- many-to-one joins. In those cases, the eager joins are
- against the parent table directly along with the
- limit/offset without the extra overhead of a subquery,
- since a many-to-one join does not add rows to the result.
-
- - Enhancements / Changes on Session.merge():
- - the "dont_load=True" flag on Session.merge() is deprecated
- and is now "load=False".
-
- - Session.merge() is performance optimized, using half the
- call counts for "load=False" mode compared to 0.5 and
- significantly fewer SQL queries in the case of collections
- for "load=True" mode.
-
- - merge() will not issue a needless merge of attributes if the
- given instance is the same instance which is already present.
-
- - merge() now also merges the "options" associated with a given
- state, i.e. those passed through query.options() which follow
- along with an instance, such as options to eagerly- or
- lazyily- load various attributes. This is essential for
- the construction of highly integrated caching schemes. This
- is a subtle behavioral change vs. 0.5.
-
- - A bug was fixed regarding the serialization of the "loader
- path" present on an instance's state, which is also necessary
- when combining the usage of merge() with serialized state
- and associated options that should be preserved.
-
- - The all new merge() is showcased in a new comprehensive
- example of how to integrate Beaker with SQLAlchemy. See
- the notes in the "examples" note below.
-
- - Primary key values can now be changed on a joined-table inheritance
- object, and ON UPDATE CASCADE will be taken into account when
- the flush happens. Set the new "passive_updates" flag to False
- on mapper() when using SQLite or MySQL/MyISAM. [ticket:1362]
-
- - flush() now detects when a primary key column was updated by
- an ON UPDATE CASCADE operation from another primary key, and
- can then locate the row for a subsequent UPDATE on the new PK
- value. This occurs when a relation() is there to establish
- the relationship as well as passive_updates=True. [ticket:1671]
-
- - the "save-update" cascade will now cascade the pending *removed*
- values from a scalar or collection attribute into the new session
- during an add() operation. This so that the flush() operation
- will also delete or modify rows of those disconnected items.
-
- - Using a "dynamic" loader with a "secondary" table now produces
- a query where the "secondary" table is *not* aliased. This
- allows the secondary Table object to be used in the "order_by"
- attribute of the relation(), and also allows it to be used
- in filter criterion against the dynamic relation.
- [ticket:1531]
-
- - relation() with uselist=False will emit a warning when
- an eager or lazy load locates more than one valid value for
- the row. This may be due to primaryjoin/secondaryjoin
- conditions which aren't appropriate for an eager LEFT OUTER
- JOIN or for other conditions. [ticket:1643]
-
- - an explicit check occurs when a synonym() is used with
- map_column=True, when a ColumnProperty (deferred or otherwise)
- exists separately in the properties dictionary sent to mapper
- with the same keyname. Instead of silently replacing
- the existing property (and possible options on that property),
- an error is raised. [ticket:1633]
-
- - a "dynamic" loader sets up its query criterion at construction
- time so that the actual query is returned from non-cloning
- accessors like "statement".
-
- - the "named tuple" objects returned when iterating a
- Query() are now pickleable.
-
- - mapping to a select() construct now requires that you
- make an alias() out of it distinctly. This to eliminate
- confusion over such issues as [ticket:1542]
-
- - query.join() has been reworked to provide more consistent
- behavior and more flexibility (includes [ticket:1537])
-
- - query.select_from() accepts multiple clauses to produce
- multiple comma separated entries within the FROM clause.
- Useful when selecting from multiple-homed join() clauses.
-
- - query.select_from() also accepts mapped classes, aliased()
- constructs, and mappers as arguments. In particular this
- helps when querying from multiple joined-table classes to ensure
- the full join gets rendered.
-
- - query.get() can be used with a mapping to an outer join
- where one or more of the primary key values are None.
- [ticket:1135]
-
- - query.from_self(), query.union(), others which do a
- "SELECT * from (SELECT...)" type of nesting will do
- a better job translating column expressions within the subquery
- to the columns clause of the outer query. This is
- potentially backwards incompatible with 0.5, in that this
- may break queries with literal expressions that do not have labels
- applied (i.e. literal('foo'), etc.)
- [ticket:1568]
-
- - relation primaryjoin and secondaryjoin now check that they
- are column-expressions, not just clause elements. this prohibits
- things like FROM expressions being placed there directly.
- [ticket:1622]
-
- - `expression.null()` is fully understood the same way
- None is when comparing an object/collection-referencing
- attribute within query.filter(), filter_by(), etc.
- [ticket:1415]
-
- - added "make_transient()" helper function which transforms a
- persistent/ detached instance into a transient one (i.e.
- deletes the instance_key and removes from any session.)
- [ticket:1052]
-
- - the allow_null_pks flag on mapper() is deprecated, and
- the feature is turned "on" by default. This means that
- a row which has a non-null value for any of its primary key
- columns will be considered an identity. The need for this
- scenario typically only occurs when mapping to an outer join.
- [ticket:1339]
-
- - the mechanics of "backref" have been fully merged into the
- finer grained "back_populates" system, and take place entirely
- within the _generate_backref() method of RelationProperty. This
- makes the initialization procedure of RelationProperty
- simpler and allows easier propagation of settings (such as from
- subclasses of RelationProperty) into the reverse reference.
- The internal BackRef() is gone and backref() returns a plain
- tuple that is understood by RelationProperty.
-
- - The version_id_col feature on mapper() will raise a warning when
- used with dialects that don't support "rowcount" adequately.
- [ticket:1569]
-
- - added "execution_options()" to Query, to so options can be
- passed to the resulting statement. Currently only
- Select-statements have these options, and the only option
- used is "stream_results", and the only dialect which knows
- "stream_results" is psycopg2.
-
- - Query.yield_per() will set the "stream_results" statement
- option automatically.
-
- - Deprecated or removed:
- * 'allow_null_pks' flag on mapper() is deprecated. It does
- nothing now and the setting is "on" in all cases.
- * 'transactional' flag on sessionmaker() and others is
- removed. Use 'autocommit=True' to indicate 'transactional=False'.
- * 'polymorphic_fetch' argument on mapper() is removed.
- Loading can be controlled using the 'with_polymorphic'
- option.
- * 'select_table' argument on mapper() is removed. Use
- 'with_polymorphic=("*", <some selectable>)' for this
- functionality.
- * 'proxy' argument on synonym() is removed. This flag
- did nothing throughout 0.5, as the "proxy generation"
- behavior is now automatic.
- * Passing a single list of elements to eagerload(),
- eagerload_all(), contains_eager(), lazyload(),
- defer(), and undefer() instead of multiple positional
- *args is deprecated.
- * Passing a single list of elements to query.order_by(),
- query.group_by(), query.join(), or query.outerjoin()
- instead of multiple positional *args is deprecated.
- * query.iterate_instances() is removed. Use query.instances().
- * Query.query_from_parent() is removed. Use the
- sqlalchemy.orm.with_parent() function to produce a
- "parent" clause, or alternatively query.with_parent().
- * query._from_self() is removed, use query.from_self()
- instead.
- * the "comparator" argument to composite() is removed.
- Use "comparator_factory".
- * RelationProperty._get_join() is removed.
- * the 'echo_uow' flag on Session is removed. Use
- logging on the "sqlalchemy.orm.unitofwork" name.
- * session.clear() is removed. use session.expunge_all().
- * session.save(), session.update(), session.save_or_update()
- are removed. Use session.add() and session.add_all().
- * the "objects" flag on session.flush() remains deprecated.
- * the "dont_load=True" flag on session.merge() is deprecated
- in favor of "load=False".
- * ScopedSession.mapper remains deprecated. See the
- usage recipe at
- http://www.sqlalchemy.org/trac/wiki/UsageRecipes/SessionAwareMapper
- * passing an InstanceState (internal SQLAlchemy state object) to
- attributes.init_collection() or attributes.get_history() is
- deprecated. These functions are public API and normally
- expect a regular mapped object instance.
- * the 'engine' parameter to declarative_base() is removed.
- Use the 'bind' keyword argument.
-
-- sql
-
- - the "autocommit" flag on select() and text() as well
- as select().autocommit() are deprecated - now call
- .execution_options(autocommit=True) on either of those
- constructs, also available directly on Connection and orm.Query.
-
- - the autoincrement flag on column now indicates the column
- which should be linked to cursor.lastrowid, if that method
- is used. See the API docs for details.
-
- - an executemany() now requires that all bound parameter
- sets require that all keys are present which are
- present in the first bound parameter set. The structure
- and behavior of an insert/update statement is very much
- determined by the first parameter set, including which
- defaults are going to fire off, and a minimum of
- guesswork is performed with all the rest so that performance
- is not impacted. For this reason defaults would otherwise
- silently "fail" for missing parameters, so this is now guarded
- against. [ticket:1566]
-
- - returning() support is native to insert(), update(),
- delete(). Implementations of varying levels of
- functionality exist for Postgresql, Firebird, MSSQL and
- Oracle. returning() can be called explicitly with column
- expressions which are then returned in the resultset,
- usually via fetchone() or first().
-
- insert() constructs will also use RETURNING implicitly to
- get newly generated primary key values, if the database
- version in use supports it (a version number check is
- performed). This occurs if no end-user returning() was
- specified.
-
- - union(), intersect(), except() and other "compound" types
- of statements have more consistent behavior w.r.t.
- parenthesizing. Each compound element embedded within
- another will now be grouped with parenthesis - previously,
- the first compound element in the list would not be grouped,
- as SQLite doesn't like a statement to start with
- parenthesis. However, Postgresql in particular has
- precedence rules regarding INTERSECT, and it is
- more consistent for parenthesis to be applied equally
- to all sub-elements. So now, the workaround for SQLite
- is also what the workaround for PG was previously -
- when nesting compound elements, the first one usually needs
- ".alias().select()" called on it to wrap it inside
- of a subquery. [ticket:1665]
-
- - insert() and update() constructs can now embed bindparam()
- objects using names that match the keys of columns. These
- bind parameters will circumvent the usual route to those
- keys showing up in the VALUES or SET clause of the generated
- SQL. [ticket:1579]
-
- - the Binary type now returns data as a Python string
- (or a "bytes" type in Python 3), instead of the built-
- in "buffer" type. This allows symmetric round trips
- of binary data. [ticket:1524]
-
- - Added a tuple_() construct, allows sets of expressions
- to be compared to another set, typically with IN against
- composite primary keys or similar. Also accepts an
- IN with multiple columns. The "scalar select can
- have only one column" error message is removed - will
- rely upon the database to report problems with
- col mismatch.
-
- - User-defined "default" and "onupdate" callables which
- accept a context should now call upon
- "context.current_parameters" to get at the dictionary
- of bind parameters currently being processed. This
- dict is available in the same way regardless of
- single-execute or executemany-style statement execution.
-
- - multi-part schema names, i.e. with dots such as
- "dbo.master", are now rendered in select() labels
- with underscores for dots, i.e. "dbo_master_table_column".
- This is a "friendly" label that behaves better
- in result sets. [ticket:1428]
-
- - removed needless "counter" behavior with select()
- labelnames that match a column name in the table,
- i.e. generates "tablename_id" for "id", instead of
- "tablename_id_1" in an attempt to avoid naming
- conflicts, when the table has a column actually
- named "tablename_id" - this is because
- the labeling logic is always applied to all columns
- so a naming conflict will never occur.
-
- - calling expr.in_([]), i.e. with an empty list, emits a warning
- before issuing the usual "expr != expr" clause. The
- "expr != expr" can be very expensive, and it's preferred
- that the user not issue in_() if the list is empty,
- instead simply not querying, or modifying the criterion
- as appropriate for more complex situations.
- [ticket:1628]
-
- - Added "execution_options()" to select()/text(), which set the
- default options for the Connection. See the note in "engines".
-
- - Deprecated or removed:
- * "scalar" flag on select() is removed, use
- select.as_scalar().
- * "shortname" attribute on bindparam() is removed.
- * postgres_returning, firebird_returning flags on
- insert(), update(), delete() are deprecated, use
- the new returning() method.
- * fold_equivalents flag on join is deprecated (will remain
- until [ticket:1131] is implemented)
-
-- engines
- - transaction isolation level may be specified with
- create_engine(... isolation_level="..."); available on
- postgresql and sqlite. [ticket:443]
-
- - Connection has execution_options(), generative method
- which accepts keywords that affect how the statement
- is executed w.r.t. the DBAPI. Currently supports
- "stream_results", causes psycopg2 to use a server
- side cursor for that statement, as well as
- "autocommit", which is the new location for the "autocommit"
- option from select() and text(). select() and
- text() also have .execution_options() as well as
- ORM Query().
-
- - fixed the import for entrypoint-driven dialects to
- not rely upon silly tb_info trick to determine import
- error status. [ticket:1630]
-
- - added first() method to ResultProxy, returns first row and
- closes result set immediately.
-
- - RowProxy objects are now pickleable, i.e. the object returned
- by result.fetchone(), result.fetchall() etc.
-
- - RowProxy no longer has a close() method, as the row no longer
- maintains a reference to the parent. Call close() on
- the parent ResultProxy instead, or use autoclose.
-
- - ResultProxy internals have been overhauled to greatly reduce
- method call counts when fetching columns. Can provide a large
- speed improvement (up to more than 100%) when fetching large
- result sets. The improvement is larger when fetching columns
- that have no type-level processing applied and when using
- results as tuples (instead of as dictionaries). Many
- thanks to Elixir's Gaëtan de Menten for this dramatic
- improvement ! [ticket:1586]
-
- - Databases which rely upon postfetch of "last inserted id"
- to get at a generated sequence value (i.e. MySQL, MS-SQL)
- now work correctly when there is a composite primary key
- where the "autoincrement" column is not the first primary
- key column in the table.
-
- - the last_inserted_ids() method has been renamed to the
- descriptor "inserted_primary_key".
-
- - setting echo=False on create_engine() now sets the loglevel
- to WARN instead of NOTSET. This so that logging can be
- disabled for a particular engine even if logging
- for "sqlalchemy.engine" is enabled overall. Note that the
- default setting of "echo" is `None`. [ticket:1554]
-
- - ConnectionProxy now has wrapper methods for all transaction
- lifecycle events, including begin(), rollback(), commit()
- begin_nested(), begin_prepared(), prepare(), release_savepoint(),
- etc.
-
- - Connection pool logging now uses both INFO and DEBUG
- log levels for logging. INFO is for major events such
- as invalidated connections, DEBUG for all the acquire/return
- logging. `echo_pool` can be False, None, True or "debug"
- the same way as `echo` works.
-
- - All pyodbc-dialects now support extra pyodbc-specific
- kw arguments 'ansi', 'unicode_results', 'autocommit'.
- [ticket:1621]
-
- - the "threadlocal" engine has been rewritten and simplified
- and now supports SAVEPOINT operations.
-
- - deprecated or removed
- * result.last_inserted_ids() is deprecated. Use
- result.inserted_primary_key
- * dialect.get_default_schema_name(connection) is now
- public via dialect.default_schema_name.
- * the "connection" argument from engine.transaction() and
- engine.run_callable() is removed - Connection itself
- now has those methods. All four methods accept
- *args and **kwargs which are passed to the given callable,
- as well as the operating connection.
-
-- schema
- - the `__contains__()` method of `MetaData` now accepts
- strings or `Table` objects as arguments. If given
- a `Table`, the argument is converted to `table.key` first,
- i.e. "[schemaname.]<tablename>" [ticket:1541]
-
- - deprecated MetaData.connect() and
- ThreadLocalMetaData.connect() have been removed - send
- the "bind" attribute to bind a metadata.
-
- - deprecated metadata.table_iterator() method removed (use
- sorted_tables)
-
- - deprecated PassiveDefault - use DefaultClause.
-
- - the "metadata" argument is removed from DefaultGenerator
- and subclasses, but remains locally present on Sequence,
- which is a standalone construct in DDL.
-
- - Removed public mutability from Index and Constraint
- objects:
- - ForeignKeyConstraint.append_element()
- - Index.append_column()
- - UniqueConstraint.append_column()
- - PrimaryKeyConstraint.add()
- - PrimaryKeyConstraint.remove()
- These should be constructed declaratively (i.e. in one
- construction).
-
- - The "start" and "increment" attributes on Sequence now
- generate "START WITH" and "INCREMENT BY" by default,
- on Oracle and Postgresql. Firebird doesn't support
- these keywords right now. [ticket:1545]
-
- - UniqueConstraint, Index, PrimaryKeyConstraint all accept
- lists of column names or column objects as arguments.
-
- - Other removed things:
- - Table.key (no idea what this was for)
- - Table.primary_key is not assignable - use
- table.append_constraint(PrimaryKeyConstraint(...))
- - Column.bind (get via column.table.bind)
- - Column.metadata (get via column.table.metadata)
- - Column.sequence (use column.default)
- - ForeignKey(constraint=some_parent) (is now private _constraint)
-
- - The use_alter flag on ForeignKey is now a shortcut option
- for operations that can be hand-constructed using the
- DDL() event system. A side effect of this refactor is
- that ForeignKeyConstraint objects with use_alter=True
- will *not* be emitted on SQLite, which does not support
- ALTER for foreign keys.
-
- - ForeignKey and ForeignKeyConstraint objects now correctly
- copy() all their public keyword arguments. [ticket:1605]
-
-- Reflection/Inspection
- - Table reflection has been expanded and generalized into
- a new API called "sqlalchemy.engine.reflection.Inspector".
- The Inspector object provides fine-grained information about
- a wide variety of schema information, with room for expansion,
- including table names, column names, view definitions, sequences,
- indexes, etc.
-
- - Views are now reflectable as ordinary Table objects. The same
- Table constructor is used, with the caveat that "effective"
- primary and foreign key constraints aren't part of the reflection
- results; these have to be specified explicitly if desired.
-
- - The existing autoload=True system now uses Inspector underneath
- so that each dialect need only return "raw" data about tables
- and other objects - Inspector is the single place that information
- is compiled into Table objects so that consistency is at a maximum.
-
-- DDL
- - the DDL system has been greatly expanded. the DDL() class
- now extends the more generic DDLElement(), which forms the basis
- of many new constructs:
-
- - CreateTable()
- - DropTable()
- - AddConstraint()
- - DropConstraint()
- - CreateIndex()
- - DropIndex()
- - CreateSequence()
- - DropSequence()
-
- These support "on" and "execute-at()" just like plain DDL()
- does. User-defined DDLElement subclasses can be created and
- linked to a compiler using the sqlalchemy.ext.compiler extension.
-
- - The signature of the "on" callable passed to DDL() and
- DDLElement() is revised as follows:
-
- "ddl" - the DDLElement object itself.
- "event" - the string event name.
- "target" - previously "schema_item", the Table or
- MetaData object triggering the event.
- "connection" - the Connection object in use for the operation.
- **kw - keyword arguments. In the case of MetaData before/after
- create/drop, the list of Table objects for which
- CREATE/DROP DDL is to be issued is passed as the kw
- argument "tables". This is necessary for metadata-level
- DDL that is dependent on the presence of specific tables.
-
- - the "schema_item" attribute of DDL has been renamed to
- "target".
-
-- dialect refactor
- - Dialect modules are now broken into database dialects
- plus DBAPI implementations. Connect URLs are now
- preferred to be specified using dialect+driver://...,
- i.e. "mysql+mysqldb://scott:tiger@localhost/test". See
- the 0.6 documentation for examples.
-
- - the setuptools entrypoint for external dialects is now
- called "sqlalchemy.dialects".
-
- - the "owner" keyword argument is removed from Table. Use
- "schema" to represent any namespaces to be prepended to
- the table name.
-
- - server_version_info becomes a static attribute.
-
- - dialects receive an initialize() event on initial
- connection to determine connection properties.
-
- - dialects receive a visit_pool event have an opportunity
- to establish pool listeners.
-
- - cached TypeEngine classes are cached per-dialect class
- instead of per-dialect.
-
- - new UserDefinedType should be used as a base class for
- new types, which preserves the 0.5 behavior of
- get_col_spec().
-
- - The result_processor() method of all type classes now
- accepts a second argument "coltype", which is the DBAPI
- type argument from cursor.description. This argument
- can help some types decide on the most efficient processing
- of result values.
-
- - Deprecated Dialect.get_params() removed.
-
- - Dialect.get_rowcount() has been renamed to a descriptor
- "rowcount", and calls cursor.rowcount directly. Dialects
- which need to hardwire a rowcount in for certain calls
- should override the method to provide different behavior.
-
- - DefaultRunner and subclasses have been removed. The job
- of this object has been simplified and moved into
- ExecutionContext. Dialects which support sequences should
- add a `fire_sequence()` method to their execution context
- implementation. [ticket:1566]
-
- - Functions and operators generated by the compiler now use
- (almost) regular dispatch functions of the form
- "visit_<opname>" and "visit_<funcname>_fn" to provide
- customed processing. This replaces the need to copy the
- "functions" and "operators" dictionaries in compiler
- subclasses with straightforward visitor methods, and also
- allows compiler subclasses complete control over
- rendering, as the full _Function or _BinaryExpression
- object is passed in.
-
-- postgresql
- - New dialects: pg8000, zxjdbc, and pypostgresql
- on py3k.
-
- - The "postgres" dialect is now named "postgresql" !
- Connection strings look like:
-
- postgresql://scott:tiger@localhost/test
- postgresql+pg8000://scott:tiger@localhost/test
-
- The "postgres" name remains for backwards compatiblity
- in the following ways:
-
- - There is a "postgres.py" dummy dialect which
- allows old URLs to work, i.e.
- postgres://scott:tiger@localhost/test
-
- - The "postgres" name can be imported from the old
- "databases" module, i.e. "from
- sqlalchemy.databases import postgres" as well as
- "dialects", "from sqlalchemy.dialects.postgres
- import base as pg", will send a deprecation
- warning.
-
- - Special expression arguments are now named
- "postgresql_returning" and "postgresql_where", but
- the older "postgres_returning" and
- "postgres_where" names still work with a
- deprecation warning.
-
- - "postgresql_where" now accepts SQL expressions which
- can also include literals, which will be quoted as needed.
-
- - The psycopg2 dialect now uses psycopg2's "unicode extension"
- on all new connections, which allows all String/Text/etc.
- types to skip the need to post-process bytestrings into
- unicode (an expensive step due to its volume). Other
- dialects which return unicode natively (pg8000, zxjdbc)
- also skip unicode post-processing.
-
- - Added new ENUM type, which exists as a schema-level
- construct and extends the generic Enum type. Automatically
- associates itself with tables and their parent metadata
- to issue the appropriate CREATE TYPE/DROP TYPE
- commands as needed, supports unicode labels, supports
- reflection. [ticket:1511]
-
- - INTERVAL supports an optional "precision" argument
- corresponding to the argument that PG accepts.
-
- - using new dialect.initialize() feature to set up
- version-dependent behavior.
-
- - somewhat better support for % signs in table/column names;
- psycopg2 can't handle a bind parameter name of
- %(foobar)s however and SQLA doesn't want to add overhead
- just to treat that one non-existent use case.
- [ticket:1279]
-
- - Inserting NULL into a primary key + foreign key column
- will allow the "not null constraint" error to raise,
- not an attempt to execute a nonexistent "col_id_seq"
- sequence. [ticket:1516]
-
- - autoincrement SELECT statements, i.e. those which
- select from a procedure that modifies rows, now work
- with server-side cursor mode (the named cursor isn't
- used for such statements.)
-
- - postgresql dialect can properly detect pg "devel" version
- strings, i.e. "8.5devel" [ticket:1636]
-
- - The psycopg2 now respects the statement option
- "stream_results". This option overrides the connection setting
- "server_side_cursors". If true, server side cursors will be
- used for the statement. If false, they will not be used, even
- if "server_side_cursors" is true on the
- connection. [ticket:1619]
-
-- mysql
- - New dialects: oursql, a new native dialect,
- MySQL Connector/Python, a native Python port of MySQLdb,
- and of course zxjdbc on Jython.
-
- - VARCHAR/NVARCHAR will not render without a length, raises
- an error before passing to MySQL. Doesn't impact
- CAST since VARCHAR is not allowed in MySQL CAST anyway,
- the dialect renders CHAR/NCHAR in those cases.
-
- - all the _detect_XXX() functions now run once underneath
- dialect.initialize()
-
- - somewhat better support for % signs in table/column names;
- MySQLdb can't handle % signs in SQL when executemany() is used,
- and SQLA doesn't want to add overhead just to treat that one
- non-existent use case. [ticket:1279]
-
- - the BINARY and MSBinary types now generate "BINARY" in all
- cases. Omitting the "length" parameter will generate
- "BINARY" with no length. Use BLOB to generate an unlengthed
- binary column.
-
- - the "quoting='quoted'" argument to MSEnum/ENUM is deprecated.
- It's best to rely upon the automatic quoting.
-
- - ENUM now subclasses the new generic Enum type, and also handles
- unicode values implicitly, if the given labelnames are unicode
- objects.
-
- - a column of type TIMESTAMP now defaults to NULL if
- "nullable=False" is not passed to Column(), and no default
- is present. This is now consistent with all other types,
- and in the case of TIMESTAMP explictly renders "NULL"
- due to MySQL's "switching" of default nullability
- for TIMESTAMP columns. [ticket:1539]
-
-- oracle
- - unit tests pass 100% with cx_oracle !
-
- - support for cx_Oracle's "native unicode" mode which does
- not require NLS_LANG to be set. Use the latest 5.0.2 or
- later of cx_oracle.
-
- - an NCLOB type is added to the base types.
-
- - use_ansi=False won't leak into the FROM/WHERE clause of
- a statement that's selecting from a subquery that also
- uses JOIN/OUTERJOIN.
-
- - added native INTERVAL type to the dialect. This supports
- only the DAY TO SECOND interval type so far due to lack
- of support in cx_oracle for YEAR TO MONTH. [ticket:1467]
-
- - usage of the CHAR type results in cx_oracle's
- FIXED_CHAR dbapi type being bound to statements.
-
- - the Oracle dialect now features NUMBER which intends
- to act justlike Oracle's NUMBER type. It is the primary
- numeric type returned by table reflection and attempts
- to return Decimal()/float/int based on the precision/scale
- parameters. [ticket:885]
-
- - func.char_length is a generic function for LENGTH
-
- - ForeignKey() which includes onupdate=<value> will emit a
- warning, not emit ON UPDATE CASCADE which is unsupported
- by oracle
-
- - the keys() method of RowProxy() now returns the result
- column names *normalized* to be SQLAlchemy case
- insensitive names. This means they will be lower case for
- case insensitive names, whereas the DBAPI would normally
- return them as UPPERCASE names. This allows row keys() to
- be compatible with further SQLAlchemy operations.
-
- - using new dialect.initialize() feature to set up
- version-dependent behavior.
-
- - using types.BigInteger with Oracle will generate
- NUMBER(19) [ticket:1125]
-
- - "case sensitivity" feature will detect an all-lowercase
- case-sensitive column name during reflect and add
- "quote=True" to the generated Column, so that proper
- quoting is maintained.
-
-- firebird
- - the keys() method of RowProxy() now returns the result
- column names *normalized* to be SQLAlchemy case
- insensitive names. This means they will be lower case for
- case insensitive names, whereas the DBAPI would normally
- return them as UPPERCASE names. This allows row keys() to
- be compatible with further SQLAlchemy operations.
-
- - using new dialect.initialize() feature to set up
- version-dependent behavior.
-
- - "case sensitivity" feature will detect an all-lowercase
- case-sensitive column name during reflect and add
- "quote=True" to the generated Column, so that proper
- quoting is maintained.
-
-- mssql
- - MSSQL + Pyodbc + FreeTDS now works for the most part,
- with possible exceptions regarding binary data as well as
- unicode schema identifiers.
- - the "has_window_funcs" flag is removed. LIMIT/OFFSET
- usage will use ROW NUMBER as always, and if on an older
- version of SQL Server, the operation fails. The behavior
- is exactly the same except the error is raised by SQL
- server instead of the dialect, and no flag setting is
- required to enable it.
- - the "auto_identity_insert" flag is removed. This feature
- always takes effect when an INSERT statement overrides a
- column that is known to have a sequence on it. As with
- "has_window_funcs", if the underlying driver doesn't
- support this, then you can't do this operation in any
- case, so there's no point in having a flag.
- - using new dialect.initialize() feature to set up
- version-dependent behavior.
- - removed references to sequence which is no longer used.
- implicit identities in mssql work the same as implicit
- sequences on any other dialects. Explicit sequences are
- enabled through the use of "default=Sequence()". See
- the MSSQL dialect documentation for more information.
-
-- sqlite
- - DATE, TIME and DATETIME types can now take optional storage_format
- and regexp argument. storage_format can be used to store those types
- using a custom string format. regexp allows to use a custom regular
- expression to match string values from the database.
- - Time and DateTime types now use by a default a stricter regular
- expression to match strings from the database. Use the regexp
- argument if you are using data stored in a legacy format.
- - __legacy_microseconds__ on SQLite Time and DateTime types is not
- supported anymore. You should use the storage_format argument
- instead.
- - Date, Time and DateTime types are now stricter in what they accept as
- bind parameters: Date type only accepts date objects (and datetime
- ones, because they inherit from date), Time only accepts time
- objects, and DateTime only accepts date and datetime objects.
- - Table() supports a keyword argument "sqlite_autoincrement", which
- applies the SQLite keyword "AUTOINCREMENT" to the single integer
- primary key column when generating DDL. Will prevent generation of
- a separate PRIMARY KEY constraint. [ticket:1016]
-
-- new dialects
- - postgresql+pg8000
- - postgresql+pypostgresql (partial)
- - postgresql+zxjdbc
- - mysql+pyodbc
- - mysql+zxjdbc
-
-- types
- - The construction of types within dialects has been totally
- overhauled. Dialects now define publically available types
- as UPPERCASE names exclusively, and internal implementation
- types using underscore identifiers (i.e. are private).
- The system by which types are expressed in SQL and DDL
- has been moved to the compiler system. This has the
- effect that there are much fewer type objects within
- most dialects. A detailed document on this architecture
- for dialect authors is in
- lib/sqlalchemy/dialects/type_migration_guidelines.txt .
-
- - Types no longer make any guesses as to default
- parameters. In particular, Numeric, Float, NUMERIC,
- FLOAT, DECIMAL don't generate any length or scale unless
- specified.
-
- - types.Binary is renamed to types.LargeBinary, it only
- produces BLOB, BYTEA, or a similar "long binary" type.
- New base BINARY and VARBINARY
- types have been added to access these MySQL/MS-SQL specific
- types in an agnostic way [ticket:1664].
-
- - String/Text/Unicode types now skip the unicode() check
- on each result column value if the dialect has
- detected the DBAPI as returning Python unicode objects
- natively. This check is issued on first connect
- using "SELECT CAST 'some text' AS VARCHAR(10)" or
- equivalent, then checking if the returned object
- is a Python unicode. This allows vast performance
- increases for native-unicode DBAPIs, including
- pysqlite/sqlite3, psycopg2, and pg8000.
-
- - Most types result processors have been checked for possible speed
- improvements. Specifically, the following generic types have been
- optimized, resulting in varying speed improvements:
- Unicode, PickleType, Interval, TypeDecorator, Binary.
- Also the following dbapi-specific implementations have been improved:
- Time, Date and DateTime on Sqlite, ARRAY on Postgresql,
- Time on MySQL, Numeric(as_decimal=False) on MySQL, oursql and
- pypostgresql, DateTime on cx_oracle and LOB-based types on cx_oracle.
-
- - Reflection of types now returns the exact UPPERCASE
- type within types.py, or the UPPERCASE type within
- the dialect itself if the type is not a standard SQL
- type. This means reflection now returns more accurate
- information about reflected types.
-
- - Added a new Enum generic type. Enum is a schema-aware object
- to support databases which require specific DDL in order to
- use enum or equivalent; in the case of PG it handles the
- details of `CREATE TYPE`, and on other databases without
- native enum support will by generate VARCHAR + an inline CHECK
- constraint to enforce the enum.
- [ticket:1109] [ticket:1511]
-
- - The Interval type includes a "native" flag which controls
- if native INTERVAL types (postgresql + oracle) are selected
- if available, or not. "day_precision" and "second_precision"
- arguments are also added which propagate as appropriately
- to these native types. Related to [ticket:1467].
-
- - The Boolean type, when used on a backend that doesn't
- have native boolean support, will generate a CHECK
- constraint "col IN (0, 1)" along with the int/smallint-
- based column type. This can be switched off if
- desired with create_constraint=False.
- Note that MySQL has no native boolean *or* CHECK constraint
- support so this feature isn't available on that platform.
- [ticket:1589]
-
- - PickleType now uses == for comparison of values when
- mutable=True, unless the "comparator" argument with a
- comparsion function is specified to the type. Objects
- being pickled will be compared based on identity (which
- defeats the purpose of mutable=True) if __eq__() is not
- overridden or a comparison function is not provided.
-
- - The default "precision" and "scale" arguments of Numeric
- and Float have been removed and now default to None.
- NUMERIC and FLOAT will be rendered with no numeric
- arguments by default unless these values are provided.
-
- - AbstractType.get_search_list() is removed - the games
- that was used for are no longer necessary.
-
- - Added a generic BigInteger type, compiles to
- BIGINT or NUMBER(19). [ticket:1125]
-
--ext
- - sqlsoup has been overhauled to explicitly support an 0.5 style
- session, using autocommit=False, autoflush=True. Default
- behavior of SQLSoup now requires the usual usage of commit()
- and rollback(), which have been added to its interface. An
- explcit Session or scoped_session can be passed to the
- constructor, allowing these arguments to be overridden.
- - sqlsoup db.<sometable>.update() and delete() now call
- query(cls).update() and delete(), respectively.
+Please see:
- - sqlsoup now has execute() and connection(), which call upon
- the Session methods of those names, ensuring that the bind is
- in terms of the SqlSoup object's bind.
+ /doc/changelog/index.html
- - sqlsoup objects no longer have the 'query' attribute - it's
- not needed for sqlsoup's usage paradigm and it gets in the
- way of a column that is actually named 'query'.
+or
- - The signature of the proxy_factory callable passed to
- association_proxy is now (lazy_collection, creator,
- value_attr, association_proxy), adding a fourth argument
- that is the parent AssociationProxy argument. Allows
- serializability and subclassing of the built in collections.
- [ticket:1259]
+ http://www.sqlalchemy.org/docs/latest/changelog/
- - association_proxy now has basic comparator methods .any(),
- .has(), .contains(), ==, !=, thanks to Scott Torborg.
- [ticket:1372]
+for an index of all changelogs.
-- examples
- - The "query_cache" examples have been removed, and are replaced
- with a fully comprehensive approach that combines the usage of
- Beaker with SQLAlchemy. New query options are used to indicate
- the caching characteristics of a particular Query, which
- can also be invoked deep within an object graph when lazily
- loading related objects. See /examples/beaker_caching/README.
-For changes prior to 0.6, see CHANGES_PRE_06
+++ /dev/null
--*- coding: utf-8; fill-column: 68 -*-
-
-===============
-CHANGES PRE-0.6
-===============
-
-0.5.9
-=====
-- sql
- - Fixed erroneous self_group() call in expression package.
- [ticket:1661]
-
-0.5.8
-=====
-- sql
- - The copy() method on Column now supports uninitialized,
- unnamed Column objects. This allows easy creation of
- declarative helpers which place common columns on multiple
- subclasses.
-
- - Default generators like Sequence() translate correctly
- across a copy() operation.
-
- - Sequence() and other DefaultGenerator objects are accepted
- as the value for the "default" and "onupdate" keyword
- arguments of Column, in addition to being accepted
- positionally.
-
- - Fixed a column arithmetic bug that affected column
- correspondence for cloned selectables which contain
- free-standing column expressions. This bug is
- generally only noticeable when exercising newer
- ORM behavior only availble in 0.6 via [ticket:1568],
- but is more correct at the SQL expression level
- as well. [ticket:1617]
-
-- postgresql
- - The extract() function, which was slightly improved in
- 0.5.7, needed a lot more work to generate the correct
- typecast (the typecasts appear to be necessary in PG's
- EXTRACT quite a lot of the time). The typecast is
- now generated using a rule dictionary based
- on PG's documentation for date/time/interval arithmetic.
- It also accepts text() constructs again, which was broken
- in 0.5.7. [ticket:1647]
-
-- firebird
- - Recognize more errors as disconnections. [ticket:1646]
-
-0.5.7
-=====
-- orm
- - contains_eager() now works with the automatically
- generated subquery that results when you say
- "query(Parent).join(Parent.somejoinedsubclass)", i.e.
- when Parent joins to a joined-table-inheritance subclass.
- Previously contains_eager() would erroneously add the
- subclass table to the query separately producing a
- cartesian product. An example is in the ticket
- description. [ticket:1543]
-
- - query.options() now only propagate to loaded objects
- for potential further sub-loads only for options where
- such behavior is relevant, keeping
- various unserializable options like those generated
- by contains_eager() out of individual instance states.
- [ticket:1553]
-
- - Session.execute() now locates table- and
- mapper-specific binds based on a passed
- in expression which is an insert()/update()/delete()
- construct. [ticket:1054]
-
- - Session.merge() now properly overwrites a many-to-one or
- uselist=False attribute to None if the attribute
- is also None in the given object to be merged.
-
- - Fixed a needless select which would occur when merging
- transient objects that contained a null primary key
- identifier. [ticket:1618]
-
- - Mutable collection passed to the "extension" attribute
- of relation(), column_property() etc. will not be mutated
- or shared among multiple instrumentation calls, preventing
- duplicate extensions, such as backref populators,
- from being inserted into the list.
- [ticket:1585]
-
- - Fixed the call to get_committed_value() on CompositeProperty.
- [ticket:1504]
-
- - Fixed bug where Query would crash if a join() with no clear
- "left" side were called when a non-mapped column entity
- appeared in the columns list. [ticket:1602]
-
- - Fixed bug whereby composite columns wouldn't load properly
- when configured on a joined-table subclass, introduced in
- version 0.5.6 as a result of the fix for [ticket:1480].
- [ticket:1616] thx to Scott Torborg.
-
- - The "use get" behavior of many-to-one relations, i.e. that a
- lazy load will fallback to the possibly cached query.get()
- value, now works across join conditions where the two compared
- types are not exactly the same class, but share the same
- "affinity" - i.e. Integer and SmallInteger. Also allows
- combinations of reflected and non-reflected types to work
- with 0.5 style type reflection, such as PGText/Text (note 0.6
- reflects types as their generic versions). [ticket:1556]
-
- - Fixed bug in query.update() when passing Cls.attribute
- as keys in the value dict and using synchronize_session='expire'
- ('fetch' in 0.6). [ticket:1436]
-
-- sql
- - Fixed bug in two-phase transaction whereby commit() method
- didn't set the full state which allows subsequent close()
- call to succeed. [ticket:1603]
-
- - Fixed the "numeric" paramstyle, which apparently is the
- default paramstyle used by Informixdb.
-
- - Repeat expressions in the columns clause of a select
- are deduped based on the identity of each clause element,
- not the actual string. This allows positional
- elements to render correctly even if they all render
- identically, such as "qmark" style bind parameters.
- [ticket:1574]
-
- - The cursor associated with connection pool connections
- (i.e. _CursorFairy) now proxies `__iter__()` to the
- underlying cursor correctly. [ticket:1632]
-
- - types now support an "affinity comparison" operation, i.e.
- that an Integer/SmallInteger are "compatible", or
- a Text/String, PickleType/Binary, etc. Part of
- [ticket:1556].
-
- - Fixed bug preventing alias() of an alias() from being
- cloned or adapted (occurs frequently in ORM operations).
- [ticket:1641]
-
-- sqlite
- - sqlite dialect properly generates CREATE INDEX for a table
- that is in an alternate schema. [ticket:1439]
-
-- postgresql
- - Added support for reflecting the DOUBLE PRECISION type,
- via a new postgres.PGDoublePrecision object.
- This is postgresql.DOUBLE_PRECISION in 0.6.
- [ticket:1085]
-
- - Added support for reflecting the INTERVAL YEAR TO MONTH
- and INTERVAL DAY TO SECOND syntaxes of the INTERVAL
- type. [ticket:460]
-
- - Corrected the "has_sequence" query to take current schema,
- or explicit sequence-stated schema, into account.
- [ticket:1576]
-
- - Fixed the behavior of extract() to apply operator
- precedence rules to the "::" operator when applying
- the "timestamp" cast - ensures proper parenthesization.
- [ticket:1611]
-
-- mssql
- - Changed the name of TrustedConnection to
- Trusted_Connection when constructing pyodbc connect
- arguments [ticket:1561]
-
-- oracle
- - The "table_names" dialect function, used by MetaData
- .reflect(), omits "index overflow tables", a system
- table generated by Oracle when "index only tables"
- with overflow are used. These tables aren't accessible
- via SQL and can't be reflected. [ticket:1637]
-
-- ext
- - A column can be added to a joined-table declarative
- superclass after the class has been constructed
- (i.e. via class-level attribute assignment), and
- the column will be propagated down to
- subclasses. [ticket:1570] This is the reverse
- situation as that of [ticket:1523], fixed in 0.5.6.
-
- - Fixed a slight inaccuracy in the sharding example.
- Comparing equivalence of columns in the ORM is best
- accomplished using col1.shares_lineage(col2).
- [ticket:1491]
-
- - Removed unused `load()` method from ShardedQuery.
- [ticket:1606]
-
-0.5.6
-=====
-- orm
- - Fixed bug whereby inheritance discriminator part of a
- composite primary key would fail on updates.
- Continuation of [ticket:1300].
-
- - Fixed bug which disallowed one side of a many-to-many
- bidirectional reference to declare itself as "viewonly"
- [ticket:1507]
-
- - Added an assertion that prevents a @validates function
- or other AttributeExtension from loading an unloaded
- collection such that internal state may be corrupted.
- [ticket:1526]
-
- - Fixed bug which prevented two entities from mutually
- replacing each other's primary key values within a single
- flush() for some orderings of operations. [ticket:1519]
-
- - Fixed an obscure issue whereby a joined-table subclass
- with a self-referential eager load on the base class
- would populate the related object's "subclass" table with
- data from the "subclass" table of the parent.
- [ticket:1485]
-
- - relations() now have greater ability to be "overridden",
- meaning a subclass that explicitly specifies a relation()
- overriding that of the parent class will be honored
- during a flush. This is currently to support
- many-to-many relations from concrete inheritance setups.
- Outside of that use case, YMMV. [ticket:1477]
-
- - Squeezed a few more unnecessary "lazy loads" out of
- relation(). When a collection is mutated, many-to-one
- backrefs on the other side will not fire off to load
- the "old" value, unless "single_parent=True" is set.
- A direct assignment of a many-to-one still loads
- the "old" value in order to update backref collections
- on that value, which may be present in the session
- already, thus maintaining the 0.5 behavioral contract.
- [ticket:1483]
-
- - Fixed bug whereby a load/refresh of joined table
- inheritance attributes which were based on
- column_property() or similar would fail to evaluate.
- [ticket:1480]
-
- - Improved support for MapperProperty objects overriding
- that of an inherited mapper for non-concrete
- inheritance setups - attribute extensions won't randomly
- collide with each other. [ticket:1488]
-
- - UPDATE and DELETE do not support ORDER BY, LIMIT, OFFSET,
- etc. in standard SQL. Query.update() and Query.delete()
- now raise an exception if any of limit(), offset(),
- order_by(), group_by(), or distinct() have been
- called. [ticket:1487]
-
- - Added AttributeExtension to sqlalchemy.orm.__all__
-
- - Improved error message when query() is called with
- a non-SQL /entity expression. [ticket:1476]
-
- - Using False or 0 as a polymorphic discriminator now
- works on the base class as well as a subclass.
- [ticket:1440]
-
- - Added enable_assertions(False) to Query which disables
- the usual assertions for expected state - used
- by Query subclasses to engineer custom state.
- [ticket:1424]. See
- http://www.sqlalchemy.org/trac/wiki/UsageRecipes/PreFilteredQuery
- for an example.
-
- - Fixed recursion issue which occured if a mapped object's
- `__len__()` or `__nonzero__()` method resulted in state
- changes. [ticket:1501]
-
- - Fixed incorrect exception raise in
- Weak/StrongIdentityMap.add()
- [ticket:1506]
-
- - Fixed the error message for "could not find a FROM clause"
- in query.join() which would fail to issue correctly
- if the query was against a pure SQL construct.
- [ticket:1522]
-
- - Fixed a somewhat hypothetical issue which would result
- in the wrong primary key being calculated for a mapper
- using the old polymorphic_union function - but this
- is old stuff. [ticket:1486]
-
-- sql
- - Fixed column.copy() to copy defaults and onupdates.
- [ticket:1373]
-
- - Fixed a bug in extract() introduced in 0.5.4 whereby
- the string "field" argument was getting treated as a
- ClauseElement, causing various errors within more
- complex SQL transformations.
-
- - Unary expressions such as DISTINCT propagate their
- type handling to result sets, allowing conversions like
- unicode and such to take place. [ticket:1420]
-
- - Fixed bug in Table and Column whereby passing empty
- dict for "info" argument would raise an exception.
- [ticket:1482]
-
-- oracle
- - Backported 0.6 fix for Oracle alias names not getting
- truncated. [ticket:1309]
-
-- ext
- - The collection proxies produced by associationproxy are now
- pickleable. A user-defined proxy_factory however
- is still not pickleable unless it defines __getstate__
- and __setstate__. [ticket:1446]
-
- - Declarative will raise an informative exception if
- __table_args__ is passed as a tuple with no dict argument.
- Improved documentation. [ticket:1468]
-
- - Table objects declared in the MetaData can now be used
- in string expressions sent to primaryjoin/secondaryjoin/
- secondary - the name is pulled from the MetaData of the
- declarative base. [ticket:1527]
-
- - A column can be added to a joined-table subclass after
- the class has been constructed (i.e. via class-level
- attribute assignment). The column is added to the underlying
- Table as always, but now the mapper will rebuild its
- "join" to include the new column, instead of raising
- an error about "no such column, use column_property()
- instead". [ticket:1523]
-
-- test
- - Added examples into the test suite so they get exercised
- regularly and cleaned up a couple deprecation warnings.
-
-
-0.5.5
-=======
-- general
- - unit tests have been migrated from unittest to nose. See
- README.unittests for information on how to run the tests.
- [ticket:970]
-
-- orm
- - The "foreign_keys" argument of relation() will now propagate
- automatically to the backref in the same way that primaryjoin
- and secondaryjoin do. For the extremely rare use case where
- the backref of a relation() has intentionally different
- "foreign_keys" configured, both sides now need to be
- configured explicity (if they do in fact require this setting,
- see the next note...).
-
- - ...the only known (and really, really rare) use case where a
- different foreign_keys setting was used on the
- forwards/backwards side, a composite foreign key that
- partially points to its own columns, has been enhanced such
- that the fk->itself aspect of the relation won't be used to
- determine relation direction.
-
- - Session.mapper is now *deprecated*.
-
- Call session.add() if you'd like a free-standing object to be
- part of your session. Otherwise, a DIY version of
- Session.mapper is now documented at
- http://www.sqlalchemy.org/trac/wiki/UsageRecipes/SessionAwareMapper
- The method will remain deprecated throughout 0.6.
-
- - Fixed Query being able to join() from individual columns of a
- joined-table subclass entity, i.e. query(SubClass.foo,
- SubcClass.bar).join(<anything>). In most cases, an error
- "Could not find a FROM clause to join from" would be
- raised. In a few others, the result would be returned in terms
- of the base class rather than the subclass - so applications
- which relied on this erroneous result need to be
- adjusted. [ticket:1431]
-
- - Fixed a bug involving contains_eager(), which would apply
- itself to a secondary (i.e. lazy) load in a particular rare
- case, producing cartesian products. improved the targeting of
- query.options() on secondary loads overall [ticket:1461].
-
- - Fixed bug introduced in 0.5.4 whereby Composite types fail
- when default-holding columns are flushed.
-
- - Fixed another 0.5.4 bug whereby mutable attributes
- (i.e. PickleType) wouldn't be deserialized correctly when the
- whole object was serialized. [ticket:1426]
-
- - Fixed bug whereby session.is_modified() would raise an
- exception if any synonyms were in use.
-
- - Fixed potential memory leak whereby previously pickled objects
- placed back in a session would not be fully garbage collected
- unless the Session were explicitly closed out.
-
- - Fixed bug whereby list-based attributes, like pickletype and
- PGArray, failed to be merged() properly.
-
- - Repaired non-working attributes.set_committed_value function.
-
- - Trimmed the pickle format for InstanceState which should
- further reduce the memory footprint of pickled instances. The
- format should be backwards compatible with that of 0.5.4 and
- previous.
-
- - sqlalchemy.orm.join and sqlalchemy.orm.outerjoin are now
- added to __all__ in sqlalchemy.orm.*. [ticket:1463]
-
- - Fixed bug where Query exception raise would fail when
- a too-short composite primary key value were passed to
- get(). [ticket:1458]
-
-- sql
- - Removed an obscure feature of execute() (including connection,
- engine, Session) whereby a bindparam() construct can be sent
- as a key to the params dictionary. This usage is undocumented
- and is at the core of an issue whereby the bindparam() object
- created implicitly by a text() construct may have the same
- hash value as a string placed in the params dictionary and may
- result in an inappropriate match when computing the final bind
- parameters. Internal checks for this condition would add
- significant latency to the critical task of parameter
- rendering, so the behavior is removed. This is a backwards
- incompatible change for any application that may have been
- using this feature, however the feature has never been
- documented.
-
-- engine/pool
- - Implemented recreate() for StaticPool.
-
-
-0.5.4p2
-=======
-
-- sql
- - Repaired the printing of SQL exceptions which are not
- based on parameters or are not executemany() style.
-
-- postgresql
- - Deprecated the hardcoded TIMESTAMP function, which when
- used as func.TIMESTAMP(value) would render "TIMESTAMP value".
- This breaks on some platforms as PostgreSQL doesn't allow
- bind parameters to be used in this context. The hard-coded
- uppercase is also inappropriate and there's lots of other
- PG casts that we'd need to support. So instead, use
- text constructs i.e. select(["timestamp '12/05/09'"]).
-
-
-0.5.4p1
-=======
-
-- orm
- - Fixed an attribute error introduced in 0.5.4 which would
- occur when merge() was used with an incomplete object.
-
-0.5.4
-=====
-
-- orm
- - Significant performance enhancements regarding Sessions/flush()
- in conjunction with large mapper graphs, large numbers of
- objects:
-
- - Removed all* O(N) scanning behavior from the flush() process,
- i.e. operations that were scanning the full session,
- including an extremely expensive one that was erroneously
- assuming primary key values were changing when this
- was not the case.
-
- * one edge case remains which may invoke a full scan,
- if an existing primary key attribute is modified
- to a new value.
-
- - The Session's "weak referencing" behavior is now *full* -
- no strong references whatsoever are made to a mapped object
- or related items/collections in its __dict__. Backrefs and
- other cycles in objects no longer affect the Session's ability
- to lose all references to unmodified objects. Objects with
- pending changes still are maintained strongly until flush.
- [ticket:1398]
-
- The implementation also improves performance by moving
- the "resurrection" process of garbage collected items
- to only be relevant for mappings that map "mutable"
- attributes (i.e. PickleType, composite attrs). This removes
- overhead from the gc process and simplifies internal
- behavior.
-
- If a "mutable" attribute change is the sole change on an object
- which is then dereferenced, the mapper will not have access to
- other attribute state when the UPDATE is issued. This may present
- itself differently to some MapperExtensions.
-
- The change also affects the internal attribute API, but not
- the AttributeExtension interface nor any of the publically
- documented attribute functions.
-
- - The unit of work no longer genererates a graph of "dependency"
- processors for the full graph of mappers during flush(), instead
- creating such processors only for those mappers which represent
- objects with pending changes. This saves a tremendous number
- of method calls in the context of a large interconnected
- graph of mappers.
-
- - Cached a wasteful "table sort" operation that previously
- occured multiple times per flush, also removing significant
- method call count from flush().
-
- - Other redundant behaviors have been simplified in
- mapper._save_obj().
-
- - Modified query_cls on DynamicAttributeImpl to accept a full
- mixin version of the AppenderQuery, which allows subclassing
- the AppenderMixin.
-
- - The "polymorphic discriminator" column may be part of a
- primary key, and it will be populated with the correct
- discriminator value. [ticket:1300]
-
- - Fixed the evaluator not being able to evaluate IS NULL clauses.
-
- - Fixed the "set collection" function on "dynamic" relations to
- initiate events correctly. Previously a collection could only
- be assigned to a pending parent instance, otherwise modified
- events would not be fired correctly. Set collection is now
- compatible with merge(), fixes [ticket:1352].
-
- - Allowed pickling of PropertyOption objects constructed with
- instrumented descriptors; previously, pickle errors would occur
- when pickling an object which was loaded with a descriptor-based
- option, such as query.options(eagerload(MyClass.foo)).
-
- - Lazy loader will not use get() if the "lazy load" SQL clause
- matches the clause used by get(), but contains some parameters
- hardcoded. Previously the lazy strategy would fail with the
- get(). Ideally get() would be used with the hardcoded
- parameters but this would require further development.
- [ticket:1357]
-
- - MapperOptions and other state associated with query.options()
- is no longer bundled within callables associated with each
- lazy/deferred-loading attribute during a load.
- The options are now associated with the instance's
- state object just once when it's populated. This removes
- the need in most cases for per-instance/attribute loader
- objects, improving load speed and memory overhead for
- individual instances. [ticket:1391]
-
- - Fixed another location where autoflush was interfering
- with session.merge(). autoflush is disabled completely
- for the duration of merge() now. [ticket:1360]
-
- - Fixed bug which prevented "mutable primary key" dependency
- logic from functioning properly on a one-to-one
- relation(). [ticket:1406]
-
- - Fixed bug in relation(), introduced in 0.5.3,
- whereby a self referential relation
- from a base class to a joined-table subclass would
- not configure correctly.
-
- - Fixed obscure mapper compilation issue when inheriting
- mappers are used which would result in un-initialized
- attributes.
-
- - Fixed documentation for session weak_identity_map -
- the default value is True, indicating a weak
- referencing map in use.
-
- - Fixed a unit of work issue whereby the foreign
- key attribute on an item contained within a collection
- owned by an object being deleted would not be set to
- None if the relation() was self-referential. [ticket:1376]
-
- - Fixed Query.update() and Query.delete() failures with eagerloaded
- relations. [ticket:1378]
-
- - It is now an error to specify both columns of a binary primaryjoin
- condition in the foreign_keys or remote_side collection. Whereas
- previously it was just nonsensical, but would succeed in a
- non-deterministic way.
-
-- schema
- - Added a quote_schema() method to the IdentifierPreparer class
- so that dialects can override how schemas get handled. This
- enables the MSSQL dialect to treat schemas as multipart
- identifiers, such as 'database.owner'. [ticket: 594, 1341]
-
-- sql
- - Back-ported the "compiler" extension from SQLA 0.6. This
- is a standardized interface which allows the creation of custom
- ClauseElement subclasses and compilers. In particular it's
- handy as an alternative to text() when you'd like to
- build a construct that has database-specific compilations.
- See the extension docs for details.
-
- - Exception messages are truncated when the list of bound
- parameters is larger than 10, preventing enormous
- multi-page exceptions from filling up screens and logfiles
- for large executemany() statements. [ticket:1413]
-
- - ``sqlalchemy.extract()`` is now dialect sensitive and can
- extract components of timestamps idiomatically across the
- supported databases, including SQLite.
-
- - Fixed __repr__() and other _get_colspec() methods on
- ForeignKey constructed from __clause_element__() style
- construct (i.e. declarative columns). [ticket:1353]
-
-- mysql
- - Reflecting a FOREIGN KEY construct will take into account
- a dotted schema.tablename combination, if the foreign key
- references a table in a remote schema. [ticket:1405]
-
-- mssql
- - Modified how savepoint logic works to prevent it from
- stepping on non-savepoint oriented routines. Savepoint
- support is still very experimental.
-
- - Added in reserved words for MSSQL that covers version 2008
- and all prior versions. [ticket:1310]
-
- - Corrected problem with information schema not working with a
- binary collation based database. Cleaned up information schema
- since it is only used by mssql now. [ticket:1343]
-
-- sqlite
- - Corrected the SLBoolean type so that it properly treats only 1
- as True. [ticket:1402]
-
- - Corrected the float type so that it correctly maps to a
- SLFloat type when being reflected. [ticket:1273]
-
-- extensions
-
- - Fixed adding of deferred or other column properties to a
- declarative class. [ticket:1379]
-
-0.5.3
-=====
-- orm
- - The "objects" argument to session.flush() is deprecated.
- State which represents the linkage between a parent and
- child object does not support "flushed" status on
- one side of the link and not the other, so supporting
- this operation leads to misleading results.
- [ticket:1315]
-
- - Query now implements __clause_element__() which produces
- its selectable, which means a Query instance can be accepted
- in many SQL expressions, including col.in_(query),
- union(query1, query2), select([foo]).select_from(query),
- etc.
-
- - Query.join() can now construct multiple FROM clauses, if
- needed. Such as, query(A, B).join(A.x).join(B.y)
- might say SELECT A.*, B.* FROM A JOIN X, B JOIN Y.
- Eager loading can also tack its joins onto those
- multiple FROM clauses. [ticket:1337]
-
- - Fixed bug in dynamic_loader() where append/remove events
- after construction time were not being propagated to the
- UOW to pick up on flush(). [ticket:1347]
-
- - Fixed bug where column_prefix wasn't being checked before
- not mapping an attribute that already had class-level
- name present.
-
- - a session.expire() on a particular collection attribute
- will clear any pending backref additions as well, so that
- the next access correctly returns only what was present
- in the database. Presents some degree of a workaround for
- [ticket:1315], although we are considering removing the
- flush([objects]) feature altogether.
-
- - Session.scalar() now converts raw SQL strings to text()
- the same way Session.execute() does and accepts same
- alternative **kw args.
-
- - improvements to the "determine direction" logic of
- relation() such that the direction of tricky situations
- like mapper(A.join(B)) -> relation-> mapper(B) can be
- determined.
-
- - When flushing partial sets of objects using session.flush([somelist]),
- pending objects which remain pending after the operation won't
- inadvertently be added as persistent. [ticket:1306]
-
- - Added "post_configure_attribute" method to InstrumentationManager,
- so that the "listen_for_events.py" example works again.
- [ticket:1314]
-
- - a forward and complementing backwards reference which are both
- of the same direction, i.e. ONETOMANY or MANYTOONE,
- is now detected, and an error message is raised.
- Saves crazy CircularDependencyErrors later on.
-
- - Fixed bugs in Query regarding simultaneous selection of
- multiple joined-table inheritance entities with common base
- classes:
-
- - previously the adaption applied to "B" on
- "A JOIN B" would be erroneously partially applied
- to "A".
-
- - comparisons on relations (i.e. A.related==someb)
- were not getting adapted when they should.
-
- - Other filterings, like
- query(A).join(A.bs).filter(B.foo=='bar'), were erroneously
- adapting "B.foo" as though it were an "A".
-
- - Fixed adaptation of EXISTS clauses via any(), has(), etc.
- in conjunction with an aliased object on the left and
- of_type() on the right. [ticket:1325]
-
- - Added an attribute helper method ``set_committed_value`` in
- sqlalchemy.orm.attributes. Given an object, attribute name,
- and value, will set the value on the object as part of its
- "committed" state, i.e. state that is understood to have
- been loaded from the database. Helps with the creation of
- homegrown collection loaders and such.
-
- - Query won't fail with weakref error when a non-mapper/class
- instrumented descriptor is passed, raises
- "Invalid column expession".
-
- - Query.group_by() properly takes into account aliasing applied
- to the FROM clause, such as with select_from(), using
- with_polymorphic(), or using from_self().
-
-- sql
- - An alias() of a select() will convert to a "scalar subquery"
- when used in an unambiguously scalar context, i.e. it's used
- in a comparison operation. This applies to
- the ORM when using query.subquery() as well.
-
- - Fixed missing _label attribute on Function object, others
- when used in a select() with use_labels (such as when used
- in an ORM column_property()). [ticket:1302]
-
- - anonymous alias names now truncate down to the max length
- allowed by the dialect. More significant on DBs like
- Oracle with very small character limits. [ticket:1309]
-
- - the __selectable__() interface has been replaced entirely
- by __clause_element__().
-
- - The per-dialect cache used by TypeEngine to cache
- dialect-specific types is now a WeakKeyDictionary.
- This to prevent dialect objects from
- being referenced forever for an application that
- creates an arbitrarily large number of engines
- or dialects. There is a small performance penalty
- which will be resolved in 0.6. [ticket:1299]
-
-- sqlite
- - Fixed SQLite reflection methods so that non-present
- cursor.description, which triggers an auto-cursor
- close, will be detected so that no results doesn't
- fail on recent versions of pysqlite which raise
- an error when fetchone() called with no rows present.
-
-- postgresql
- - Index reflection won't fail when an index with
- multiple expressions is encountered.
-
- - Added PGUuid and PGBit types to
- sqlalchemy.databases.postgres. [ticket:1327]
-
- - Refection of unknown PG types won't crash when those
- types are specified within a domain. [ticket:1327]
-
-- mssql
- - Preliminary support for pymssql 1.0.1
-
- - Corrected issue on mssql where max_identifier_length was
- not being respected.
-
-- extensions
-
- - Fixed a recursive pickling issue in serializer, triggered
- by an EXISTS or other embedded FROM construct.
-
- - Declarative locates the "inherits" class using a search
- through __bases__, to skip over mixins that are local
- to subclasses.
-
- - Declarative figures out joined-table inheritance primary join
- condition even if "inherits" mapper argument is given
- explicitly.
-
- - Declarative will properly interpret the "foreign_keys" argument
- on a backref() if it's a string.
-
- - Declarative will accept a table-bound column as a property
- when used in conjunction with __table__, if the column is already
- present in __table__. The column will be remapped to the given
- key the same way as when added to the mapper() properties dict.
-
-0.5.2
-======
-
-- orm
- - Further refined 0.5.1's warning about delete-orphan cascade
- placed on a many-to-many relation. First, the bad news:
- the warning will apply to both many-to-many as well as
- many-to-one relations. This is necessary since in both
- cases, SQLA does not scan the full set of potential parents
- when determining "orphan" status - for a persistent object
- it only detects an in-python de-association event to establish
- the object as an "orphan". Next, the good news: to support
- one-to-one via a foreign key or assocation table, or to
- support one-to-many via an association table, a new flag
- single_parent=True may be set which indicates objects
- linked to the relation are only meant to have a single parent.
- The relation will raise an error if multiple parent-association
- events occur within Python.
-
- - Adjusted the attribute instrumentation change from 0.5.1 to
- fully establish instrumentation for subclasses where the mapper
- was created after the superclass had already been fully
- instrumented. [ticket:1292]
-
- - Fixed bug in delete-orphan cascade whereby two one-to-one
- relations from two different parent classes to the same target
- class would prematurely expunge the instance.
-
- - Fixed an eager loading bug whereby self-referential eager
- loading would prevent other eager loads, self referential or not,
- from joining to the parent JOIN properly. Thanks to Alex K
- for creating a great test case.
-
- - session.expire() and related methods will not expire() unloaded
- deferred attributes. This prevents them from being needlessly
- loaded when the instance is refreshed.
-
- - query.join()/outerjoin() will now properly join an aliased()
- construct to the existing left side, even if query.from_self()
- or query.select_from(someselectable) has been called.
- [ticket:1293]
-
-- sql
- - Further fixes to the "percent signs and spaces in column/table
- names" functionality. [ticket:1284]
-
-- mssql
- - Restored convert_unicode handling. Results were being passed
- on through without conversion. [ticket:1291]
-
- - Really fixing the decimal handling this time. [ticket:1282].
-
- - Modified table reflection code to use only kwargs when
- constructing tables. [Ticket:1289]
-
-0.5.1
-========
-
-- orm
- - Removed an internal join cache which could potentially leak
- memory when issuing query.join() repeatedly to ad-hoc
- selectables.
-
- - The "clear()", "save()", "update()", "save_or_update()"
- Session methods have been deprecated, replaced by
- "expunge_all()" and "add()". "expunge_all()" has also
- been added to ScopedSession.
-
- - Modernized the "no mapped table" exception and added a more
- explicit __table__/__tablename__ exception to declarative.
-
- - Concrete inheriting mappers now instrument attributes which
- are inherited from the superclass, but are not defined for
- the concrete mapper itself, with an InstrumentedAttribute that
- issues a descriptive error when accessed. [ticket:1237]
-
- - Added a new `relation()` keyword `back_populates`. This
- allows configuation of backreferences using explicit
- relations. [ticket:781] This is required when creating
- bidirectional relations between a hierarchy of concrete
- mappers and another class. [ticket:1237]
-
- - Test coverage added for `relation()` objects specified on
- concrete mappers. [ticket:1237]
-
- - Query.from_self() as well as query.subquery() both disable
- the rendering of eager joins inside the subquery produced.
- The "disable all eager joins" feature is available publically
- via a new query.enable_eagerloads() generative. [ticket:1276]
-
- - Added a rudimental series of set operations to Query that
- receive Query objects as arguments, including union(),
- union_all(), intersect(), except_(), insertsect_all(),
- except_all(). See the API documentation for
- Query.union() for examples.
-
- - Fixed bug that prevented Query.join() and eagerloads from
- attaching to a query that selected from a union or aliased union.
-
- - A short documentation example added for bidirectional
- relations specified on concrete mappers. [ticket:1237]
-
- - Mappers now instrument class attributes upon construction
- with the final InstrumentedAttribute object which remains
- persistent. The `_CompileOnAttr`/`__getattribute__()`
- methodology has been removed. The net effect is that
- Column-based mapped class attributes can now be used fully
- at the class level without invoking a mapper compilation
- operation, greatly simplifying typical usage patterns
- within declarative. [ticket:1269]
-
- - ColumnProperty (and front-end helpers such as ``deferred``) no
- longer ignores unknown **keyword arguments.
-
- - Fixed a bug with the unitofwork's "row switch" mechanism,
- i.e. the conversion of INSERT/DELETE into an UPDATE, when
- combined with joined-table inheritance and an object
- which contained no defined values for the child table where
- an UPDATE with no SET clause would be rendered.
-
- - Using delete-orphan on a many-to-many relation is deprecated.
- This produces misleading or erroneous results since SQLA does
- not retrieve the full list of "parents" for m2m. To get delete-orphan
- behavior with an m2m table, use an explcit association class
- so that the individual association row is treated as a parent.
- [ticket:1281]
-
- - delete-orphan cascade always requires delete cascade. Specifying
- delete-orphan without delete now raises a deprecation warning.
- [ticket:1281]
-
-- sql
- - Improved the methodology to handling percent signs in column
- names from [ticket:1256]. Added more tests. MySQL and
- PostgreSQL dialects still do not issue correct CREATE TABLE
- statements for identifiers with percent signs in them.
-
-- schema
- - Index now accepts column-oriented InstrumentedAttributes
- (i.e. column-based mapped class attributes) as column
- arguments. [ticket:1214]
-
- - Column with no name (as in declarative) won't raise a
- NoneType error when it's string output is requsted
- (such as in a stack trace).
-
- - Fixed bug when overriding a Column with a ForeignKey
- on a reflected table, where derived columns (i.e. the
- "virtual" columns of a select, etc.) would inadvertently
- call upon schema-level cleanup logic intended only
- for the original column. [ticket:1278]
-
-- declarative
- - Can now specify Column objects on subclasses which have no
- table of their own (i.e. use single table inheritance).
- The columns will be appended to the base table, but only
- mapped by the subclass.
-
- - For both joined and single inheriting subclasses, the subclass
- will only map those columns which are already mapped on the
- superclass and those explicit on the subclass. Other
- columns that are present on the `Table` will be excluded
- from the mapping by default, which can be disabled
- by passing a blank `exclude_properties` collection to the
- `__mapper_args__`. This is so that single-inheriting
- classes which define their own columns are the only classes
- to map those columns. The effect is actually a more organized
- mapping than you'd normally get with explicit `mapper()`
- calls unless you set up the `exclude_properties` arguments
- explicitly.
-
- - It's an error to add new Column objects to a declarative class
- that specified an existing table using __table__.
-
-- mysql
- - Added the missing keywords from MySQL 4.1 so they get escaped
- properly.
-
-- mssql
- - Corrected handling of large decimal values with more robust
- tests. Removed string manipulation on floats. [ticket:1280]
-
- - Modified the do_begin handling in mssql to use the Cursor not
- the Connection so it is DBAPI compatible.
-
- - Corrected SAVEPOINT support on adodbapi by changing the
- handling of savepoint_release, which is unsupported on mssql.
-
-0.5.0
-========
-
-- new features
-- general
- - Documentation has been converted to Sphinx. In particular,
- the generated API documentation has been constructed into a
- full blown "API Reference" section which organizes editorial
- documentation combined with generated docstrings. Cross
- linking between sections and API docs are vastly improved, a
- javascript-powered search feature is provided, and a full
- index of all classes, functions and members is provided.
-
- - setup.py now imports setuptools only optionally. If not
- present, distutils is used. The new "pip" installer is
- recommended over easy_install as it installs in a more
- simplified way.
-
- - added an extremely basic illustration of a PostGIS integration
- to the examples folder.
-
-- orm
- - Query.with_polymorphic() now accepts a third argument
- "discriminator" which will replace the value of
- mapper.polymorphic_on for that query. Mappers themselves no
- longer require polymorphic_on to be set, even if the mapper
- has a polymorphic_identity. When not set, the mapper will
- load non-polymorphically by default. Together, these two
- features allow a non-polymorphic concrete inheritance setup to
- use polymorphic loading on a per-query basis, since concrete
- setups are prone to many issues when used polymorphically in
- all cases.
-
- - dynamic_loader accepts a query_class= to customize the Query
- classes used for both the dynamic collection and the queries
- built from it.
-
- - query.order_by() accepts None which will remove any pending
- order_by state from the query, as well as cancel out any
- mapper/relation configured ordering. This is primarily useful
- for overriding the ordering specified on a dynamic_loader().
- [ticket:1079]
-
-- sql
- - RowProxy objects can be used in place of dictionary arguments
- sent to connection.execute() and friends. [ticket:935]
-
-- dialect
- - Added a new description_encoding attribute on the dialect that
- is used for encoding the column name when processing the
- metadata. This usually defaults to utf-8.
-
-- mssql
- - Added in a new MSGenericBinary type. This maps to the Binary
- type so it can implement the specialized behavior of treating
- length specified types as fixed-width Binary types and
- non-length types as an unbound variable length Binary type.
-
- - Added in new types: MSVarBinary and MSImage. [ticket:1249]
-
- - Added in the MSReal, MSNText, MSSmallDateTime, MSTime,
- MSDateTimeOffset, and MSDateTime2 types
-
-- sqlite
- - Table reflection now stores the actual DefaultClause value for
- the column. [ticket:1266]
-
-- bugfixes, behavioral changes
-- general
-- orm
- - Exceptions raised during compile_mappers() are now preserved
- to provide "sticky behavior" - if a hasattr() call on a
- pre-compiled mapped attribute triggers a failing compile and
- suppresses the exception, subsequent compilation is blocked
- and the exception will be reiterated on the next compile()
- call. This issue occurs frequently when using declarative.
-
- - property.of_type() is now recognized on a single-table
- inheriting target, when used in the context of
- prop.of_type(..).any()/has(), as well as
- query.join(prop.of_type(...)).
-
- - query.join() raises an error when the target of the join
- doesn't match the property-based attribute - while it's
- unlikely anyone is doing this, the SQLAlchemy author was
- guilty of this particular loosey-goosey behavior.
-
- - Fixed bug when using weak_instance_map=False where modified
- events would not be intercepted for a flush(). [ticket:1272]
-
- - Fixed some deep "column correspondence" issues which could
- impact a Query made against a selectable containing multiple
- versions of the same table, as well as unions and similar
- which contained the same table columns in different column
- positions at different levels. [ticket:1268]
-
- - Custom comparator classes used in conjunction with
- column_property(), relation() etc. can define new comparison
- methods on the Comparator, which will become available via
- __getattr__() on the InstrumentedAttribute. In the case of
- synonym() or comparable_property(), attributes are resolved
- first on the user-defined descriptor, then on the user-defined
- comparator.
-
- - Added ScopedSession.is_active accessor. [ticket:976]
-
- - Can pass mapped attributes and column objects as keys to
- query.update({}). [ticket:1262]
-
- - Mapped attributes passed to the values() of an expression
- level insert() or update() will use the keys of the mapped
- columns, not that of the mapped attribute.
-
- - Corrected problem with Query.delete() and Query.update() not
- working properly with bind parameters. [ticket:1242]
-
- - Query.select_from(), from_statement() ensure that the given
- argument is a FromClause, or Text/Select/Union, respectively.
-
- - Query() can be passed a "composite" attribute as a column
- expression and it will be expanded. Somewhat related to
- [ticket:1253].
-
- - Query() is a little more robust when passed various column
- expressions such as strings, clauselists, text() constructs
- (which may mean it just raises an error more nicely).
-
- - first() works as expected with Query.from_statement().
-
- - Fixed bug introduced in 0.5rc4 involving eager loading not
- functioning for properties which were added to a mapper
- post-compile using add_property() or equivalent.
-
- - Fixed bug where many-to-many relation() with viewonly=True
- would not correctly reference the link between
- secondary->remote.
-
- - Duplicate items in a list-based collection will be maintained
- when issuing INSERTs to a "secondary" table in a many-to-many
- relation. Assuming the m2m table has a unique or primary key
- constraint on it, this will raise the expected constraint
- violation instead of silently dropping the duplicate
- entries. Note that the old behavior remains for a one-to-many
- relation since collection entries in that case don't result in
- INSERT statements and SQLA doesn't manually police
- collections. [ticket:1232]
-
- - Query.add_column() can accept FromClause objects in the same
- manner as session.query() can.
-
- - Comparison of many-to-one relation to NULL is properly
- converted to IS NOT NULL based on not_().
-
- - Extra checks added to ensure explicit
- primaryjoin/secondaryjoin are ClauseElement instances, to
- prevent more confusing errors later on. [ticket:1087]
-
- - Improved mapper() check for non-class classes. [ticket:1236]
-
- - comparator_factory argument is now documented and supported by
- all MapperProperty types, including column_property(),
- relation(), backref(), and synonym() [ticket:5051].
-
- - Changed the name of PropertyLoader to RelationProperty, to be
- consistent with all the other names. PropertyLoader is still
- present as a synonym.
-
- - fixed "double iter()" call causing bus errors in shard API,
- removed errant result.close() left over from the 0.4
- version. [ticket:1099] [ticket:1228]
-
- - made Session.merge cascades not trigger autoflush. Fixes
- merged instances getting prematurely inserted with missing
- values.
-
- - Two fixes to help prevent out-of-band columns from being
- rendered in polymorphic_union inheritance scenarios (which
- then causes extra tables to be rendered in the FROM clause
- causing cartesian products):
-
- - improvements to "column adaption" for a->b->c inheritance
- situations to better locate columns that are related to
- one another via multiple levels of indirection, rather
- than rendering the non-adapted column.
-
- - the "polymorphic discriminator" column is only rendered
- for the actual mapper being queried against. The column
- won't be "pulled in" from a subclass or superclass mapper
- since it's not needed.
-
- - Fixed shard_id argument on ShardedSession.execute().
- [ticket:1072]
-
-- sql
- - Columns can again contain percent signs within their
- names. [ticket:1256]
-
- - sqlalchemy.sql.expression.Function is now a public class. It
- can be subclassed to provide user-defined SQL functions in an
- imperative style, including with pre-established behaviors.
- The postgis.py example illustrates one usage of this.
-
- - PickleType now favors == comparison by default, if the
- incoming object (such as a dict) implements __eq__(). If the
- object does not implement __eq__() and mutable=True, a
- deprecation warning is raised.
-
- - Fixed the import weirdness in sqlalchemy.sql to not export
- __names__ [ticket:1215].
-
- - Using the same ForeignKey object repeatedly raises an error
- instead of silently failing later. [ticket:1238]
-
- - Added NotImplementedError for params() method on
- Insert/Update/Delete constructs. These items currently don't
- support this functionality, which also would be a little
- misleading compared to values().
-
- - Reflected foreign keys will properly locate their referenced
- column, even if the column was given a "key" attribute
- different from the reflected name. This is achieved via a new
- flag on ForeignKey/ForeignKeyConstraint called "link_to_name",
- if True means the given name is the referred-to column's name,
- not its assigned key. [ticket:650]
-
- - select() can accept a ClauseList as a column in the same way
- as a Table or other selectable and the interior expressions
- will be used as column elements. [ticket:1253]
-
- - the "passive" flag on session.is_modified() is correctly
- propagated to the attribute manager.
-
- - union() and union_all() will not whack any order_by() that has
- been applied to the select()s inside. If you union() a
- select() with order_by() (presumably to support LIMIT/OFFSET),
- you should also call self_group() on it to apply parenthesis.
-
-- engine/pool
-
- - Connection.invalidate() checks for closed status to avoid
- attribute errors. [ticket:1246]
-
- - NullPool supports reconnect on failure behavior.
- [ticket:1094]
-
- - Added a mutex for the initial pool creation when using
- pool.manage(dbapi). This prevents a minor case of "dogpile"
- behavior which would otherwise occur upon a heavy load
- startup. [ticket:799]
-
- - _execute_clauseelement() goes back to being a private method.
- Subclassing Connection is not needed now that ConnectionProxy
- is available.
-
-- documentation
- - Tickets [ticket:1200] [ticket:1149].
-
- - Added note about create_session() defaults.
-
- - Added section about metadata.reflect().
-
- - Updated `TypeDecorator` section.
-
- - Rewrote the "threadlocal" strategy section of the docs due to
- recent confusion over this feature.
-
- - Removed badly out of date 'polymorphic_fetch' and
- 'select_table' docs from inheritance, reworked the second half
- of "joined table inheritance".
-
- - Documented `comparator_factory` kwarg, added new doc section
- "Custom Comparators".
-
-- mssql
- - Refactored the Date/Time types. The ``smalldatetime`` data
- type no longer truncates to a date only, and will now be
- mapped to the MSSmallDateTime type. [ticket:1254]
-
- - Corrected an issue with Numerics to accept an int.
-
- - Mapped ``char_length`` to the ``LEN()`` function.
-
- - If an ``INSERT`` includes a subselect the ``INSERT`` is
- converted from an ``INSERT INTO VALUES`` construct to a
- ``INSERT INTO SELECT`` construct.
-
- - If the column is part of a ``primary_key`` it will be ``NOT
- NULL`` since MSSQL doesn't allow ``NULL`` in primary_key
- columns.
-
- - ``MSBinary`` now returns a ``BINARY`` instead of an
- ``IMAGE``. This is a backwards incompatible change in that
- ``BINARY`` is a fixed length data type whereas ``IMAGE`` is a
- variable length data type. [ticket:1249]
-
- - ``get_default_schema_name`` is now reflected from the database
- based on the user's default schema. This only works with MSSQL
- 2005 and later. [ticket:1258]
-
- - Added collation support through the use of a new collation
- argument. This is supported on the following types: char,
- nchar, varchar, nvarchar, text, ntext. [ticket:1248]
-
- - Changes to the connection string parameters favor DSN as the
- default specification for pyodbc. See the mssql.py docstring
- for detailed usage instructions.
-
- - Added experimental support of savepoints. It currently does
- not work fully with sessions.
-
- - Support for three levels of column nullability: NULL, NOT
- NULL, and the database's configured default. The default
- Column configuration (nullable=True) will now generate NULL in
- the DDL. Previously no specification was emitted and the
- database default would take effect (usually NULL, but not
- always). To explicitly request the database default,
- configure columns with nullable=None and no specification will
- be emitted in DDL. This is backwards incompatible
- behavior. [ticket:1243]
-
-- postgres
- - "%" signs in text() constructs are automatically escaped to
- "%%". Because of the backwards incompatible nature of this
- change, a warning is emitted if '%%' is detected in the
- string. [ticket:1267]
-
- - Calling alias.execute() in conjunction with
- server_side_cursors won't raise AttributeError.
-
- - Added Index reflection support to PostgreSQL, using a great
- patch we long neglected, submitted by Ken
- Kuhlman. [ticket:714]
-
-- oracle
- - Adjusted the format of create_xid() to repair two-phase
- commit. We now have field reports of Oracle two-phase commit
- working properly with this change.
-
- - Added OracleNVarchar type, produces NVARCHAR2, and also
- subclasses Unicode so that convert_unicode=True by default.
- NVARCHAR2 reflects into this type automatically so these
- columns pass unicode on a reflected table with no explicit
- convert_unicode=True flags. [ticket:1233]
-
- - Fixed bug which was preventing out params of certain types
- from being received; thanks a ton to huddlej at wwu.edu !
- [ticket:1265]
-
-- mysql
- - "%" signs in text() constructs are automatically escaped to
- "%%". Because of the backwards incompatible nature of this
- change, a warning is emitted if '%%' is detected in the
- string.
-
- - Fixed bug in exception raise when FK columns not present
- during reflection. [ticket:1241]
-
- - Fixed bug involving reflection of a remote-schema table with a
- foreign key ref to another table in that schema.
-
-- associationproxy
- - The association proxy properties are make themselves available
- at the class level, e.g. MyClass.aproxy. Previously this
- evaluated to None.
-
-- declarative
- - The full list of arguments accepted as string by backref()
- includes 'primaryjoin', 'secondaryjoin', 'secondary',
- 'foreign_keys', 'remote_side', 'order_by'.
-
-0.5.0rc4
-========
-- features
-- orm
- - Query.count() has been enhanced to do the "right thing" in a
- wider variety of cases. It can now count multiple-entity
- queries, as well as column-based queries. Note that this means
- if you say query(A, B).count() without any joining criterion,
- it's going to count the cartesian product of A*B. Any query
- which is against column-based entities will automatically
- issue "SELECT count(1) FROM (SELECT...)" so that the real
- rowcount is returned, meaning a query such as
- query(func.count(A.name)).count() will return a value of one,
- since that query would return one row.
-
- - Lots of performance tuning. A rough guesstimate over various
- ORM operations places it 10% faster over 0.5.0rc3, 25-30% over
- 0.4.8.
-
-- bugfixes and behavioral changes
-- general:
- - global "propigate"->"propagate" change.
-
-- orm
- - Adjustments to the enhanced garbage collection on
- InstanceState to better guard against errors due to lost
- state.
-
- - Query.get() returns a more informative error message when
- executed against multiple entities. [ticket:1220]
-
- - Restored NotImplementedError on Cls.relation.in_()
- [ticket:1140] [ticket:1221]
-
- - Fixed PendingDeprecationWarning involving order_by parameter
- on relation(). [ticket:1226]
-
-- sql
- - Removed the 'properties' attribute of the Connection object,
- Connection.info should be used.
-
- - Restored "active rowcount" fetch before ResultProxy autocloses
- the cursor. This was removed in 0.5rc3.
-
- - Rearranged the `load_dialect_impl()` method in `TypeDecorator`
- such that it will take effect even if the user-defined
- `TypeDecorator` uses another `TypeDecorator` as its impl.
-
-- access
- - Added support for Currency type.
-
- - Functions were not return their result. [ticket:1017]
-
- - Corrected problem with joins. Access only support LEFT OUTER
- or INNER not just JOIN by itself. [ticket:1017]
-
-- mssql
- - Lots of cleanup and fixes to correct problems with limit and
- offset.
-
- - Correct situation where subqueries as part of a binary
- expression need to be translated to use the IN and NOT IN
- syntax.
-
- - Fixed E Notation issue that prevented the ability to insert
- decimal values less than 1E-6. [ticket:1216]
-
- - Corrected problems with reflection when dealing with schemas,
- particularly when those schemas are the default
- schema. [ticket:1217]
-
- - Corrected problem with casting a zero length item to a
- varchar. It now correctly adjusts the CAST.
-
-- ext
- - Can now use a custom "inherit_condition" in __mapper_args__
- when using declarative.
-
- - fixed string-based "remote_side", "order_by" and others not
- propagating correctly when used in backref().
-
-0.5.0rc3
-========
-- features
-- orm
- - Added two new hooks to SessionExtension: after_bulk_delete()
- and after_bulk_update(). after_bulk_delete() is called after
- a bulk delete() operation on a query. after_bulk_update() is
- called after a bulk update() operation on a query.
-
-- sql
- - SQL compiler optimizations and complexity reduction. The call
- count for compiling a typical select() construct is 20% less
- versus 0.5.0rc2.
-
- - Dialects can now generate label names of adjustable
- length. Pass in the argument "label_length=<value>" to
- create_engine() to adjust how many characters max will be
- present in dynamically generated column labels, i.e.
- "somecolumn AS somelabel". Any value less than 6 will result
- in a label of minimal size, consisting of an underscore and a
- numeric counter. The compiler uses the value of
- dialect.max_identifier_length as a default. [ticket:1211]
-
-- ext
- - Added a new extension sqlalchemy.ext.serializer. Provides
- Serializer/Deserializer "classes" which mirror
- Pickle/Unpickle, as well as dumps() and loads(). This
- serializer implements an "external object" pickler which keeps
- key context-sensitive objects, including engines, sessions,
- metadata, Tables/Columns, and mappers, outside of the pickle
- stream, and can later restore the pickle using any
- engine/metadata/session provider. This is used not for
- pickling regular object instances, which are pickleable
- without any special logic, but for pickling expression objects
- and full Query objects, such that all mapper/engine/session
- dependencies can be restored at unpickle time.
-
-- oracle
- - Wrote a docstring for Oracle dialect. Apparently that Ohloh
- "few source code comments" label is starting to sting :).
-
- - Removed FIRST_ROWS() optimize flag when using LIMIT/OFFSET,
- can be reenabled with optimize_limits=True create_engine()
- flag. [ticket:536]
-
-- bugfixes and behavioral changes
-- orm
- - "not equals" comparisons of simple many-to-one relation to an
- instance will not drop into an EXISTS clause and will compare
- foreign key columns instead.
-
- - Removed not-really-working use cases of comparing a collection
- to an iterable. Use contains() to test for collection
- membership.
-
- - Improved the behavior of aliased() objects such that they more
- accurately adapt the expressions generated, which helps
- particularly with self-referential comparisons. [ticket:1171]
-
- - Fixed bug involving primaryjoin/secondaryjoin conditions
- constructed from class-bound attributes (as often occurs when
- using declarative), which later would be inappropriately
- aliased by Query, particularly with the various EXISTS based
- comparators.
-
- - Fixed bug when using multiple query.join() with an
- aliased-bound descriptor which would lose the left alias.
-
- - Improved weakref identity map memory management to no longer
- require mutexing, resurrects garbage collected instance on a
- lazy basis for an InstanceState with pending changes.
-
- - InstanceState object now removes circular references to itself
- upon disposal to keep it outside of cyclic garbage collection.
-
- - relation() won't hide unrelated ForeignKey errors inside of
- the "please specify primaryjoin" message when determining join
- condition.
-
- - Fixed bug in Query involving order_by() in conjunction with
- multiple aliases of the same class (will add tests in
- [ticket:1218])
-
- - When using Query.join() with an explicit clause for the ON
- clause, the clause will be aliased in terms of the left side
- of the join, allowing scenarios like query(Source).
- from_self().join((Dest, Source.id==Dest.source_id)) to work
- properly.
-
- - polymorphic_union() function respects the "key" of each Column
- if they differ from the column's name.
-
- - Repaired support for "passive-deletes" on a many-to-one
- relation() with "delete" cascade. [ticket:1183]
-
- - Fixed bug in composite types which prevented a primary-key
- composite type from being mutated [ticket:1213].
-
- - Added more granularity to internal attribute access, such that
- cascade and flush operations will not initialize unloaded
- attributes and collections, leaving them intact for a
- lazy-load later on. Backref events still initialize attrbutes
- and collections for pending instances. [ticket:1202]
-
-- sql
- - Simplified the check for ResultProxy "autoclose without
- results" to be based solely on presence of
- cursor.description. All the regexp-based guessing about
- statements returning rows has been removed [ticket:1212].
-
- - Direct execution of a union() construct will properly set up
- result-row processing. [ticket:1194]
-
- - The internal notion of an "OID" or "ROWID" column has been
- removed. It's basically not used by any dialect, and the
- possibility of its usage with psycopg2's cursor.lastrowid is
- basically gone now that INSERT..RETURNING is available.
-
- - Removed "default_order_by()" method on all FromClause objects.
-
- - Repaired the table.tometadata() method so that a passed-in
- schema argument is propagated to ForeignKey constructs.
-
- - Slightly changed behavior of IN operator for comparing to
- empty collections. Now results in inequality comparison
- against self. More portable, but breaks with stored procedures
- that aren't pure functions.
-
-- oracle
- - Setting the auto_convert_lobs to False on create_engine() will
- also instruct the OracleBinary type to return the cx_oracle
- LOB object unchanged.
-
-- mysql
- - Fixed foreign key reflection in the edge case where a Table's
- explicit schema= is the same as the schema (database) the
- connection is attached to.
-
- - No longer expects include_columns in table reflection to be
- lower case.
-
-- ext
- - Fixed bug preventing declarative-bound "column" objects from
- being used in column_mapped_collection(). [ticket:1174]
-
-- misc
- - util.flatten_iterator() func doesn't interpret strings with
- __iter__() methods as iterators, such as in pypy
- [ticket:1077].
-
-0.5.0rc2
-========
-- orm
- - Fixed bug involving read/write relation()s that contain
- literal or other non-column expressions within their
- primaryjoin condition equated to a foreign key column.
-
- - "non-batch" mode in mapper(), a feature which allows mapper
- extension methods to be called as each instance is
- updated/inserted, now honors the insert order of the objects
- given.
-
- - Fixed RLock-related bug in mapper which could deadlock upon
- reentrant mapper compile() calls, something that occurs when
- using declarative constructs inside of ForeignKey objects.
-
- - ScopedSession.query_property now accepts a query_cls factory,
- overriding the session's configured query_cls.
-
- - Fixed shared state bug interfering with ScopedSession.mapper's
- ability to apply default __init__ implementations on object
- subclasses.
-
- - Fixed up slices on Query (i.e. query[x:y]) to work properly
- for zero length slices, slices with None on either end.
- [ticket:1177]
-
- - Added an example illustrating Celko's "nested sets" as a
- SQLA mapping.
-
- - contains_eager() with an alias argument works even when
- the alias is embedded in a SELECT, as when sent to the
- Query via query.select_from().
-
- - contains_eager() usage is now compatible with a Query that
- also contains a regular eager load and limit/offset, in that
- the columns are added to the Query-generated subquery.
- [ticket:1180]
-
- - session.execute() will execute a Sequence object passed to
- it (regression from 0.4).
-
- - Removed the "raiseerror" keyword argument from object_mapper()
- and class_mapper(). These functions raise in all cases
- if the given class/instance is not mapped.
-
- - Fixed session.transaction.commit() on a autocommit=False
- session not starting a new transaction.
-
- - Some adjustments to Session.identity_map's weak referencing
- behavior to reduce asynchronous GC side effects.
-
- - Adjustment to Session's post-flush accounting of newly
- "clean" objects to better protect against operating on
- objects as they're asynchronously gc'ed. [ticket:1182]
-
-- sql
- - column.in_(someselect) can now be used as a columns-clause
- expression without the subquery bleeding into the FROM clause
- [ticket:1074]
-
-- sqlite
- - Overhauled SQLite date/time bind/result processing to use
- regular expressions and format strings, rather than
- strptime/strftime, to generically support pre-1900 dates,
- dates with microseconds. [ticket:968]
-
- - String's (and Unicode's, UnicodeText's, etc.) convert_unicode
- logic disabled in the sqlite dialect, to adjust for pysqlite
- 2.5.0's new requirement that only Python unicode objects are
- accepted;
- http://itsystementwicklung.de/pipermail/list-pysqlite/2008-March/000018.html
-
-- mysql
- - Temporary tables are now reflectable.
-
-- oracle
- - Oracle will detect string-based statements which contain
- comments at the front before a SELECT as SELECT statements.
- [ticket:1187]
-
-0.5.0rc1
-========
-
-- orm
- - Query now has delete() and update(values) methods. This allows
- to perform bulk deletes/updates with the Query object.
-
- - The RowTuple object returned by Query(*cols) now features
- keynames which prefer mapped attribute names over column keys,
- column keys over column names, i.e. Query(Class.foo,
- Class.bar) will have names "foo" and "bar" even if those are
- not the names of the underlying Column objects. Direct Column
- objects such as Query(table.c.col) will return the "key"
- attribute of the Column.
-
- - Added scalar() and value() methods to Query, each return a
- single scalar value. scalar() takes no arguments and is
- roughly equivalent to first()[0], value()
- takes a single column expression and is roughly equivalent to
- values(expr).next()[0].
-
- - Improved the determination of the FROM clause when placing SQL
- expressions in the query() list of entities. In particular
- scalar subqueries should not "leak" their inner FROM objects
- out into the enclosing query.
-
- - Joins along a relation() from a mapped class to a mapped
- subclass, where the mapped subclass is configured with single
- table inheritance, will include an IN clause which limits the
- subtypes of the joined class to those requested, within the ON
- clause of the join. This takes effect for eager load joins as
- well as query.join(). Note that in some scenarios the IN
- clause will appear in the WHERE clause of the query as well
- since this discrimination has multiple trigger points.
-
- - AttributeExtension has been refined such that the event
- is fired before the mutation actually occurs. Additionally,
- the append() and set() methods must now return the given value,
- which is used as the value to be used in the mutation operation.
- This allows creation of validating AttributeListeners which
- raise before the action actually occurs, and which can change
- the given value into something else before its used.
-
- - column_property(), composite_property(), and relation() now
- accept a single or list of AttributeExtensions using the
- "extension" keyword argument.
-
- - query.order_by().get() silently drops the "ORDER BY" from
- the query issued by GET but does not raise an exception.
-
- - Added a Validator AttributeExtension, as well as a
- @validates decorator which is used in a similar fashion
- as @reconstructor, and marks a method as validating
- one or more mapped attributes.
-
- - class.someprop.in_() raises NotImplementedError pending the
- implementation of "in_" for relation [ticket:1140]
-
- - Fixed primary key update for many-to-many collections where
- the collection had not been loaded yet [ticket:1127]
-
- - Fixed bug whereby deferred() columns with a group in conjunction
- with an otherwise unrelated synonym() would produce
- an AttributeError during deferred load.
-
- - The before_flush() hook on SessionExtension takes place before
- the list of new/dirty/deleted is calculated for the final
- time, allowing routines within before_flush() to further
- change the state of the Session before the flush proceeds.
- [ticket:1128]
-
- - The "extension" argument to Session and others can now
- optionally be a list, supporting events sent to multiple
- SessionExtension instances. Session places SessionExtensions
- in Session.extensions.
-
- - Reentrant calls to flush() raise an error. This also serves
- as a rudimentary, but not foolproof, check against concurrent
- calls to Session.flush().
-
- - Improved the behavior of query.join() when joining to
- joined-table inheritance subclasses, using explicit join
- criteria (i.e. not on a relation).
-
- - @orm.attributes.reconstitute and
- MapperExtension.reconstitute have been renamed to
- @orm.reconstructor and MapperExtension.reconstruct_instance
-
- - Fixed @reconstructor hook for subclasses which inherit from a
- base class. [ticket:1129]
-
- - The composite() property type now supports a
- __set_composite_values__() method on the composite class which
- is required if the class represents state using attribute
- names other than the column's keynames; default-generated
- values now get populated properly upon flush. Also,
- composites with attributes set to None compare correctly.
- [ticket:1132]
-
- - The 3-tuple of iterables returned by attributes.get_history()
- may now be a mix of lists and tuples. (Previously members
- were always lists.)
-
- - Fixed bug whereby changing a primary key attribute on an
- entity where the attribute's previous value had been expired
- would produce an error upon flush(). [ticket:1151]
-
- - Fixed custom instrumentation bug whereby get_instance_dict()
- was not called for newly constructed instances not loaded
- by the ORM.
-
- - Session.delete() adds the given object to the session if
- not already present. This was a regression bug from 0.4.
- [ticket:1150]
-
- - The `echo_uow` flag on `Session` is deprecated, and unit-of-work
- logging is now application-level only, not per-session level.
-
- - Removed conflicting `contains()` operator from
- `InstrumentedAttribute` which didn't accept `escape` kwaarg
- [ticket:1153].
-
-- declarative
- - Fixed bug whereby mapper couldn't initialize if a composite
- primary key referenced another table that was not defined
- yet. [ticket:1161]
-
- - Fixed exception throw which would occur when string-based
- primaryjoin condition was used in conjunction with backref.
-
-- schema
- - Added "sorted_tables" accessor to MetaData, which returns
- Table objects sorted in order of dependency as a list.
- This deprecates the MetaData.table_iterator() method.
- The "reverse=False" keyword argument has also been
- removed from util.sort_tables(); use the Python
- 'reversed' function to reverse the results.
- [ticket:1033]
-
- - The 'length' argument to all Numeric types has been renamed
- to 'scale'. 'length' is deprecated and is still accepted
- with a warning.
-
- - Dropped 0.3-compatibility for user defined types
- (convert_result_value, convert_bind_param).
-
-- sql
- - Temporarily rolled back the "ORDER BY" enhancement from
- [ticket:1068]. This feature is on hold pending further
- development.
-
- - The exists() construct won't "export" its contained list
- of elements as FROM clauses, allowing them to be used more
- effectively in the columns clause of a SELECT.
-
- - and_() and or_() now generate a ColumnElement, allowing
- boolean expressions as result columns, i.e.
- select([and_(1, 0)]). [ticket:798]
-
- - Bind params now subclass ColumnElement which allows them to be
- selectable by orm.query (they already had most ColumnElement
- semantics).
-
- - Added select_from() method to exists() construct, which becomes
- more and more compatible with a regular select().
-
- - Added func.min(), func.max(), func.sum() as "generic functions",
- which basically allows for their return type to be determined
- automatically. Helps with dates on SQLite, decimal types,
- others. [ticket:1160]
-
- - added decimal.Decimal as an "auto-detect" type; bind parameters
- and generic functions will set their type to Numeric when a
- Decimal is used.
-
-- mysql
- - The 'length' argument to MSInteger, MSBigInteger, MSTinyInteger,
- MSSmallInteger and MSYear has been renamed to 'display_width'.
-
- - Added MSMediumInteger type [ticket:1146].
-
- - the function func.utc_timestamp() compiles to UTC_TIMESTAMP, without
- the parenthesis, which seem to get in the way when using in
- conjunction with executemany().
-
-- oracle
- - limit/offset no longer uses ROW NUMBER OVER to limit rows,
- and instead uses subqueries in conjunction with a special
- Oracle optimization comment. Allows LIMIT/OFFSET to work
- in conjunction with DISTINCT. [ticket:536]
- - has_sequence() now takes the current "schema" argument into
- account [ticket:1155]
- - added BFILE to reflected type names [ticket:1121]
-
-0.5beta3
-========
-
-0.5beta3 includes all bugfixes listed under release "0.4.7".
-
-- orm
- - The "entity_name" feature of SQLAlchemy mappers has been
- removed. For rationale, see http://tinyurl.com/6nm2ne
-
- - the "autoexpire" flag on Session, sessionmaker(), and
- scoped_session() has been renamed to "expire_on_commit". It
- does not affect the expiration behavior of rollback().
-
- - fixed endless loop bug which could occur within a mapper's
- deferred load of inherited attributes.
-
- - a legacy-support flag "_enable_transaction_accounting" flag
- added to Session which when False, disables all
- transaction-level object accounting, including expire on
- rollback, expire on commit, new/deleted list maintenance, and
- autoflush on begin.
-
- - The 'cascade' parameter to relation() accepts None as a value,
- which is equivalent to no cascades.
-
- - A critical fix to dynamic relations allows the "modified"
- history to be properly cleared after a flush().
-
- - user-defined @properties on a class are detected and left in
- place during mapper initialization. This means that a
- table-bound column of the same name will not be mapped at all
- if a @property is in the way (and the column is not remapped
- to a different name), nor will an instrumented attribute from
- an inherited class be applied. The same rules apply for names
- excluded using the include_properties/exclude_properties
- collections.
-
- - Added a new SessionExtension hook called after_attach(). This
- is called at the point of attachment for objects via add(),
- add_all(), delete(), and merge().
-
- - A mapper which inherits from another, when inheriting the
- columns of its inherited mapper, will use any reassigned
- property names specified in that inheriting mapper.
- Previously, if "Base" had reassigned "base_id" to the name
- "id", "SubBase(Base)" would still get an attribute called
- "base_id". This could be worked around by explicitly stating
- the column in each submapper as well but this is fairly
- unworkable and also impossible when using declarative
- [ticket:1111].
-
- - Fixed a series of potential race conditions in Session whereby
- asynchronous GC could remove unmodified, no longer referenced
- items from the session as they were present in a list of items
- to be processed, typically during session.expunge_all() and
- dependent methods.
-
- - Some improvements to the _CompileOnAttr mechanism which should
- reduce the probability of "Attribute x was not replaced during
- compile" warnings. (this generally applies to SQLA hackers,
- like Elixir devs).
-
- - Fixed bug whereby the "unsaved, pending instance" FlushError
- raised for a pending orphan would not take superclass mappers
- into account when generating the list of relations responsible
- for the error.
-
-- sql
- - func.count() with no arguments renders as COUNT(*), equivalent
- to func.count(text('*')).
-
- - simple label names in ORDER BY expressions render as
- themselves, and not as a re-statement of their corresponding
- expression. This feature is currently enabled only for
- SQLite, MySQL, and PostgreSQL. It can be enabled on other
- dialects as each is shown to support this
- behavior. [ticket:1068]
-
-- ext
- - Class-bound attributes sent as arguments to relation()'s
- remote_side and foreign_keys parameters are now accepted,
- allowing them to be used with declarative. Additionally fixed
- bugs involving order_by being specified as a class-bound
- attribute in conjunction with eager loading.
-
- - declarative initialization of Columns adjusted so that
- non-renamed columns initialize in the same way as a non
- declarative mapper. This allows an inheriting mapper to set
- up its same-named "id" columns in particular such that the
- parent "id" column is favored over the child column, reducing
- database round trips when this value is requested.
-
-- mysql
- - Quoting of MSEnum values for use in CREATE TABLE is now
- optional & will be quoted on demand as required. (Quoting was
- always optional for use with existing tables.) [ticket:1110]
-
-0.5beta2
-========
-
-0.5beta2 includes some of the bugfixes listed under release "0.4.7".
-
-- orm
- - In addition to expired attributes, deferred attributes also
- load if their data is present in the result set. [ticket:870]
-
- - session.refresh() raises an informative error message if the
- list of attributes does not include any column-based
- attributes.
-
- - query() raises an informative error message if no columns or
- mappers are specified.
-
- - lazy loaders now trigger autoflush before proceeding. This
- allows expire() of a collection or scalar relation to function
- properly in the context of autoflush.
-
- - column_property() attributes which represent SQL expressions
- or columns that are not present in the mapped tables (such as
- those from views) are automatically expired after an INSERT or
- UPDATE, assuming they have not been locally modified, so that
- they are refreshed with the most recent data upon access.
- [ticket:887]
-
- - Fixed explicit, self-referential joins between two
- joined-table inheritance mappers when using query.join(cls,
- aliased=True). [ticket:1082]
-
- - Fixed query.join() when used in conjunction with a
- columns-only clause and an SQL-expression ON clause in the
- join.
-
- - The "allow_column_override" flag from mapper() has been
- removed. This flag is virtually always misunderstood. Its
- specific functionality is available via the
- include_properties/exclude_properties mapper arguments.
-
- - Repaired `__str__()` method on Query. [ticket:1066]
-
- - Session.bind gets used as a default even when table/mapper
- specific binds are defined.
-
-- schema
- - Added prefixes option to `Table` that accepts a list of
- strings to insert after CREATE in the CREATE TABLE statement.
- [ticket:1075]
-
- - Unicode, UnicodeText types now set "assert_unicode" and
- "convert_unicode" by default, but accept overriding
- **kwargs for these values.
-
-- sql
- - Added new match() operator that performs a full-text search.
- Supported on PostgreSQL, SQLite, MySQL, MS-SQL, and Oracle
- backends.
-
-- sqlite
- - Modified SQLite's representation of "microseconds" to match
- the output of str(somedatetime), i.e. in that the microseconds
- are represented as fractional seconds in string format. This
- makes SQLA's SQLite date type compatible with datetimes that
- were saved directly using Pysqlite (which just calls str()).
- Note that this is incompatible with the existing microseconds
- values in a SQLA 0.4 generated SQLite database file.
-
- To get the old behavior globally:
-
- from sqlalchemy.databases.sqlite import DateTimeMixin
- DateTimeMixin.__legacy_microseconds__ = True
-
- To get the behavior on individual DateTime types:
-
- t = sqlite.SLDateTime()
- t.__legacy_microseconds__ = True
-
- Then use "t" as the type on the Column.
-
- [ticket:1090]
-
- - SQLite Date, DateTime, and Time types only accept Python
- datetime objects now, not strings. If you'd like to format
- dates as strings yourself with SQLite, use a String type. If
- you'd like them to return datetime objects anyway despite
- their accepting strings as input, make a TypeDecorator around
- String - SQLA doesn't encourage this pattern.
-
-- extensions
- - Declarative supports a __table_args__ class variable, which is
- either a dictionary, or tuple of the form (arg1, arg2, ...,
- {kwarg1:value, ...}) which contains positional + kw arguments
- to be passed to the Table constructor. [ticket:1096]
-
-0.5beta1
-========
-
-An ongoing document describing the changes from 0.4 to 0.5 is at:
-http://www.sqlalchemy.org/trac/wiki/05Migration
-
-For this section, the list below primarily lists changes within the
-attribute instrumentation API and is only a small fraction of the
-full changes between 0.4/0.5.
-
--orm
- - The "__init__" trigger/decorator added by mapper now attempts
- to exactly mirror the argument signature of the original
- __init__. The pass-through for '_sa_session' is no longer
- implicit- you must allow for this keyword argument in your
- constructor.
-
- - ClassState is renamed to ClassManager.
-
- - Classes may supply their own InstrumentationManager by
- providing a __sa_instrumentation_manager__ property.
-
- - Custom instrumentation may use any mechanism to associate a
- ClassManager with a class and an InstanceState with an
- instance. Attributes on those objects are still the default
- association mechanism used by SQLAlchemy's native
- instrumentation.
-
- - Moved entity_name, _sa_session_id, and _instance_key from the
- instance object to the instance state. These values are still
- available in the old way, which is now deprecated, using
- descriptors attached to the class. A deprecation warning will
- be issued when accessed.
-
- - The _prepare_instrumentation alias for prepare_instrumentation
- has been removed.
-
- - sqlalchemy.exceptions has been renamed to sqlalchemy.exc. The
- module may be imported under either name.
-
- - ORM-related exceptions are now defined in sqlalchemy.orm.exc.
- ConcurrentModificationError, FlushError, and
- UnmappedColumnError compatibility aliases are installed in
- sqlalchemy.exc during the import of sqlalchemy.orm.
-
- - sqlalchemy.logging has been renamed to sqlalchemy.log.
-
- - The transitional sqlalchemy.log.SADeprecationWarning alias for
- the warning's definition in sqlalchemy.exc has been removed.
-
- - exc.AssertionError has been removed and usage replaced with
- Python's built-in AssertionError.
-
- - The behavior of MapperExtensions attached to multiple,
- entity_name= primary mappers for a single class has been
- altered. The first mapper() defined for a class is the only
- mapper eligible for the MapperExtension 'instrument_class',
- 'init_instance' and 'init_failed' events. This is backwards
- incompatible; previously the extensions of last mapper defined
- would receive these events.
-
-- firebird
- - Added support for returning values from inserts (2.0+ only),
- updates and deletes (2.1+ only).
-
-0.4.9 (unreleased)
-==================
-
-- general:
- - global "propigate"->"propagate" change.
-
-- orm
- - polymorphic_union() function respects the "key" of each
- Column if they differ from the column's name.
-
- - Fixed 0.4-only bug preventing composite columns
- from working properly with inheriting mappers
- [ticket:1199]
-
- - Fixed RLock-related bug in mapper which could deadlock upon
- reentrant mapper compile() calls, something that occurs when
- using declarative constructs inside of ForeignKey objects.
- Ported from 0.5.
-
- - Fixed bug in composite types which prevented a primary-key
- composite type from being mutated [ticket:1213].
-
- - Added ScopedSession.is_active accessor. [ticket:976]
-
- - Class-bound accessor can be used as the argument to
- relation() order_by. [ticket:939]
-
- - Fixed shard_id argument on ShardedSession.execute().
- [ticket:1072]
-
-- sql
- - Connection.invalidate() checks for closed status
- to avoid attribute errors. [ticket:1246]
-
- - NullPool supports reconnect on failure behavior.
- [ticket:1094]
-
- - The per-dialect cache used by TypeEngine to cache
- dialect-specific types is now a WeakKeyDictionary.
- This to prevent dialect objects from
- being referenced forever for an application that
- creates an arbitrarily large number of engines
- or dialects. There is a small performance penalty
- which will be resolved in 0.6. [ticket:1299]
-
--sqlite
- - Fixed SQLite reflection methods so that non-present
- cursor.description, which triggers an auto-cursor
- close, will be detected so that no results doesn't
- fail on recent versions of pysqlite which raise
- an error when fetchone() called with no rows present.
-
-- postgres
- - Added Index reflection support to Postgres, using a
- great patch we long neglected, submitted by
- Ken Kuhlman. [ticket:714]
-
-- mysql
- - Fixed bug in exception raise when FK columns not present
- during reflection. [ticket:1241]
-
-- oracle
- - Fixed bug which was preventing out params of certain types
- from being received; thanks a ton to huddlej at wwu.edu !
- [ticket:1265]
-
-0.4.8
-=====
-- orm
- - Fixed bug regarding inherit_condition passed
- with "A=B" versus "B=A" leading to errors
- [ticket:1039]
-
- - Changes made to new, dirty and deleted
- collections in
- SessionExtension.before_flush() will take
- effect for that flush.
-
- - Added label() method to InstrumentedAttribute
- to establish forwards compatibility with 0.5.
-
-- sql
- - column.in_(someselect) can now be used as
- a columns-clause expression without the subquery
- bleeding into the FROM clause [ticket:1074]
-
-- mysql
- - Added MSMediumInteger type [ticket:1146].
-
-- sqlite
- - Supplied a custom strftime() function which
- handles dates before 1900. [ticket:968]
-
- - String's (and Unicode's, UnicodeText's, etc.)
- convert_unicode logic disabled in the sqlite dialect,
- to adjust for pysqlite 2.5.0's new requirement that
- only Python unicode objects are accepted;
- http://itsystementwicklung.de/pipermail/list-pysqlite/2008-March/000018.html
-
-- oracle
- - has_sequence() now takes schema name into account
- [ticket:1155]
- - added BFILE to the list of reflected types
- [ticket:1121]
-
-0.4.7p1
-=====
-- orm
- - Added "add()" and "add_all()" to scoped_session
- methods. Workaround for 0.4.7:
-
- from sqlalchemy.orm.scoping import ScopedSession,\
- instrument
- setattr(
- ScopedSession, "add", instrument("add"))
- setattr(
- ScopedSession, "add_all", instrument("add_all"))
-
- - Fixed non-2.3 compatible usage of set() and generator
- expression within relation().
-
-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
-
-
-from . import autodoc_mods, dialect_info, sqlformatter, mako
+from . import autodoc_mods, dialect_info, sqlformatter, mako, changelog
def setup(app):
app.add_config_value('release_date', "", True)
autodoc_mods.setup(app)
dialect_info.setup(app)
sqlformatter.setup(app)
+ changelog.setup(app)
--- /dev/null
+import re
+from sphinx.util.compat import Directive
+from docutils.statemachine import StringList
+from docutils import nodes
+import textwrap
+import itertools
+import collections
+
+def _comma_list(text):
+ return re.split(r"\s*,\s*", text.strip())
+
+def _parse_content(content):
+ d = {}
+ d['text'] = []
+ idx = 0
+ for line in content:
+ idx += 1
+ m = re.match(r' *\:(.+?)\:(?: +(.+))?', line)
+ if m:
+ attrname, value = m.group(1, 2)
+ d[attrname] = value or ''
+ else:
+ break
+ d["text"] = content[idx:]
+ return d
+
+def _ticketurl(ticket):
+ return "http://www.sqlalchemy.org/trac/ticket/%s" % ticket
+
+class EnvDirective(object):
+ @property
+ def env(self):
+ return self.state.document.settings.env
+
+class ChangeLogDirective(EnvDirective, Directive):
+ has_content = True
+
+ type_ = "change"
+
+ sections = _comma_list("general, orm, orm declarative, orm querying, \
+ orm configuration, engine, sql, \
+ schema, \
+ postgresql, mysql, sqlite, mssql, oracle, firebird, misc")
+
+ subsections = ["feature", "bug", "moved", "changed", "removed", ""]
+
+
+ def _organize_by_section(self, changes):
+ compound_sections = [(s, s.split(" ")) for s in
+ self.sections if " " in s]
+
+ bysection = collections.defaultdict(list)
+ for rec in changes:
+ subsection = rec['tags'].intersection(self.subsections)
+ if subsection:
+ subsection = subsection.pop()
+ else:
+ subsection = ""
+
+ for compound, comp_words in compound_sections:
+ if rec['tags'].issuperset(comp_words):
+ bysection[(compound, subsection)].append(rec)
+ break
+
+ intersect = rec['tags'].intersection(self.sections)
+ if intersect:
+ bysection[(intersect.pop(), subsection)].append(rec)
+ continue
+
+ bysection[('misc', subsection)].append(rec)
+ return bysection
+
+ @classmethod
+ def changes(cls, env):
+ return env.temp_data['ChangeLogDirective_%s_changes' % cls.type_]
+
+ def _setup_run(self):
+ self.env.temp_data['ChangeLogDirective_%s_changes' % self.type_] = []
+ self._parsed_content = _parse_content(self.content)
+
+ p = nodes.paragraph('', '',)
+ self.state.nested_parse(self.content[1:], 0, p)
+
+ def run(self):
+ self._setup_run()
+ changes = self.changes(self.env)
+ output = []
+
+ version = self._parsed_content.get('version', '')
+ id_prefix = "%s-%s" % (self.type_, version)
+ topsection = self._run_top(id_prefix)
+ output.append(topsection)
+
+ bysection = self._organize_by_section(changes)
+
+ counter = itertools.count()
+
+ for section in self.sections:
+ sec, append_sec = self._section(section, id_prefix)
+
+ for cat in self.subsections:
+ for rec in bysection[(section, cat)]:
+ rec["id"] = "%s-%s" % (id_prefix, next(counter))
+
+ self._render_rec(rec, section, cat, append_sec)
+
+ if append_sec.children:
+ topsection.append(sec)
+
+ return output
+
+ def _section(self, section, id_prefix):
+ bullets = nodes.bullet_list()
+ sec = nodes.section('',
+ nodes.title(section, section),
+ bullets,
+ ids=["%s-%s" % (id_prefix, section.replace(" ", "-"))]
+ )
+ return sec, bullets
+
+ def _run_top(self, id_prefix):
+ version = self._parsed_content.get('version', '')
+ topsection = nodes.section('',
+ nodes.title(version, version),
+ ids=[id_prefix]
+ )
+
+ if self._parsed_content.get("released"):
+ topsection.append(nodes.Text("Released: %s" % self._parsed_content['released']))
+ else:
+ topsection.append(nodes.Text("no release date"))
+ return topsection
+
+ def _render_rec(self, rec, section, cat, append_sec):
+ para = rec['node'].deepcopy()
+ insert_ticket = nodes.paragraph('')
+ para.append(insert_ticket)
+
+ for i, ticket in enumerate(rec['tickets']):
+ if i > 0:
+ insert_ticket.append(nodes.Text(", ", ", "))
+ else:
+ insert_ticket.append(nodes.Text(" ", " "))
+ insert_ticket.append(
+ nodes.reference('', '',
+ nodes.Text("#%s" % ticket, "#%s" % ticket),
+ refuri=_ticketurl(ticket)
+ )
+ )
+
+ if cat or rec['tags']:
+ #tag_node = nodes.strong('',
+ # "[" + cat + "] "
+ # )
+ tag_node = nodes.strong('',
+ " ".join("[%s]" % t for t
+ in
+ [cat] +
+ list(rec['tags'].difference([cat]))
+ if t
+ ) + " "
+ )
+ para.children[0].insert(0, tag_node)
+
+ append_sec.append(
+ nodes.list_item('',
+ nodes.target('', '', ids=[rec['id']]),
+ para
+ )
+ )
+
+
+class MigrationLogDirective(ChangeLogDirective):
+ type_ = "migration"
+
+ sections = _comma_list("New Features, Behavioral Changes, Removed")
+
+ subsections = _comma_list("general, orm, orm declarative, orm querying, \
+ orm configuration, engine, sql, \
+ postgresql, mysql, sqlite")
+
+ def _run_top(self, id_prefix):
+ version = self._parsed_content.get('version', '')
+ title = "What's new in %s?" % version
+ topsection = nodes.section('',
+ nodes.title(title, title),
+ ids=[id_prefix]
+ )
+ if "released" in self._parsed_content:
+ topsection.append(nodes.Text("Released: %s" % self._parsed_content['released']))
+ return topsection
+
+ def _section(self, section, id_prefix):
+ sec = nodes.section('',
+ nodes.title(section, section),
+ ids=["%s-%s" % (id_prefix, section.replace(" ", "-"))]
+ )
+ return sec, sec
+
+ def _render_rec(self, rec, section, cat, append_sec):
+ para = rec['node'].deepcopy()
+
+ insert_ticket = nodes.paragraph('')
+ para.append(insert_ticket)
+
+ for i, ticket in enumerate(rec['tickets']):
+ if i > 0:
+ insert_ticket.append(nodes.Text(", ", ", "))
+ else:
+ insert_ticket.append(nodes.Text(" ", " "))
+ insert_ticket.append(
+ nodes.reference('', '',
+ nodes.Text("#%s" % ticket, "#%s" % ticket),
+ refuri=_ticketurl(ticket)
+ )
+ )
+
+ append_sec.append(
+ nodes.section('',
+ nodes.title(rec['title'], rec['title']),
+ para,
+ ids=[rec['id']]
+ )
+ )
+
+
+
+class ChangeDirective(EnvDirective, Directive):
+ has_content = True
+
+ type_ = "change"
+ parent_cls = ChangeLogDirective
+
+ def run(self):
+ content = _parse_content(self.content)
+ p = nodes.paragraph('', '',)
+ rec = {
+ 'tags': set(_comma_list(content.get('tags', ''))).difference(['']),
+ 'tickets': set(_comma_list(content.get('tickets', ''))).difference(['']),
+ 'node': p,
+ 'type': self.type_,
+ "title": content.get("title", None)
+ }
+
+ if "declarative" in rec['tags']:
+ rec['tags'].add("orm")
+
+ self.state.nested_parse(content['text'], 0, p)
+ self.parent_cls.changes(self.env).append(rec)
+
+ return []
+
+class MigrationDirective(ChangeDirective):
+ type_ = "migration"
+ parent_cls = MigrationLogDirective
+
+
+def _rst2sphinx(text):
+ return StringList(
+ [line.strip() for line in textwrap.dedent(text).split("\n")]
+ )
+
+def setup(app):
+ app.add_directive('changelog', ChangeLogDirective)
+ app.add_directive('migrationlog', MigrationLogDirective)
+ app.add_directive('migration', MigrationDirective)
+ app.add_directive('change', ChangeDirective)
+
if "connectstring" in content:
- # TODO: wish I knew how to just embed RST here and parse it into
- # nodes
sec = nodes.section(
'',
nodes.title("Connecting", "Connecting"),
--- /dev/null
+
+==============
+0.1 Changelog
+==============
+
+
+.. changelog::
+ :version: 0.1.7
+ :released: Fri May 05 2006
+
+ .. change::
+ :tags:
+ :tickets:
+
+ some fixes to topological sort algorithm
+
+ .. change::
+ :tags:
+ :tickets:
+
+ added DISTINCT ON support to Postgres (just supply distinct=[col1,col2..])
+
+ .. change::
+ :tags:
+ :tickets:
+
+ added __mod__ (% operator) to sql expressions
+
+ .. change::
+ :tags:
+ :tickets:
+
+ "order_by" mapper property inherited from inheriting mapper
+
+ .. change::
+ :tags:
+ :tickets:
+
+ fix to column type used when mapper UPDATES/DELETEs
+
+ .. change::
+ :tags:
+ :tickets:
+
+ with convert_unicode=True, reflection was failing, has been fixed
+
+ .. change::
+ :tags:
+ :tickets:
+
+ types types types! still werent working....have to use TypeDecorator again :(
+
+ .. change::
+ :tags:
+ :tickets:
+
+ mysql binary type converts array output to buffer, fixes PickleType
+
+ .. change::
+ :tags:
+ :tickets:
+
+ fixed the attributes.py memory leak once and for all
+
+ .. change::
+ :tags:
+ :tickets:
+
+ unittests are qualified based on the databases that support each one
+
+ .. change::
+ :tags:
+ :tickets:
+
+ fixed bug where column defaults would clobber VALUES clause of insert objects
+
+ .. change::
+ :tags:
+ :tickets:
+
+ fixed bug where table def w/ schema name would force engine connection
+
+ .. change::
+ :tags:
+ :tickets:
+
+ fix for parenthesis to work correctly with subqueries in INSERT/UPDATE
+
+ .. change::
+ :tags:
+ :tickets:
+
+ HistoryArraySet gets extend() method
+
+ .. change::
+ :tags:
+ :tickets:
+
+ fixed lazyload support for other comparison operators besides =
+
+ .. change::
+ :tags:
+ :tickets:
+
+ lazyload fix where two comparisons in the join condition point to the
+ samem column
+
+ .. change::
+ :tags:
+ :tickets:
+
+ added "construct_new" flag to mapper, will use __new__ to create instances
+ instead of __init__ (standard in 0.2)
+
+ .. change::
+ :tags:
+ :tickets:
+
+ added selectresults.py to SVN, missed it last time
+
+ .. change::
+ :tags:
+ :tickets:
+
+ tweak to allow a many-to-many relationship from a table to itself via
+ an association table
+
+ .. change::
+ :tags:
+ :tickets:
+
+ small fix to "translate_row" function used by polymorphic example
+
+ .. change::
+ :tags:
+ :tickets:
+
+ create_engine uses cgi.parse_qsl to read query string (out the window in 0.2)
+
+ .. change::
+ :tags:
+ :tickets:
+
+ tweaks to CAST operator
+
+ .. change::
+ :tags:
+ :tickets:
+
+ fixed function names LOCAL_TIME/LOCAL_TIMESTAMP -> LOCALTIME/LOCALTIMESTAMP
+
+ .. change::
+ :tags:
+ :tickets:
+
+ fixed order of ORDER BY/HAVING in compile
+
+.. changelog::
+ :version: 0.1.6
+ :released: Wed Apr 12 2006
+
+ .. change::
+ :tags:
+ :tickets:
+
+ support for MS-SQL added courtesy Rick Morrison, Runar Petursson
+
+ .. change::
+ :tags:
+ :tickets:
+
+ the latest SQLSoup from J. Ellis
+
+ .. change::
+ :tags:
+ :tickets:
+
+ ActiveMapper has preliminary support for inheritance (Jeff Watkins)
+
+ .. change::
+ :tags:
+ :tickets:
+
+ added a "mods" system which allows pluggable modules that modify/augment
+ core functionality, using the function "install_mods(*modnames)".
+
+ .. change::
+ :tags:
+ :tickets:
+
+ added the first "mod", SelectResults, which modifies mapper selects to
+ return generators that turn ranges into LIMIT/OFFSET queries
+ (Jonas Borgstr?
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ overhaul to the attributes system. code has been clarified, and also fixed to
+ support proper polymorphic behavior on object attributes.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ added "for_update" flag to Select objects
+
+ .. change::
+ :tags:
+ :tickets:
+
+ some fixes for backrefs
+
+ .. change::
+ :tags:
+ :tickets:
+
+ fix for postgres1 DateTime type
+
+ .. change::
+ :tags:
+ :tickets:
+
+ documentation pages mostly switched over to Markdown syntax
+
+.. changelog::
+ :version: 0.1.5
+ :released: Mon Mar 27 2006
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ factored apart objectstore/unitofwork to separate "Session scoping" from
+ "uow commit heavy lifting"
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ fixed Oracle8-compatibility "use_ansi" flag which converts JOINs to
+ comparisons with the = and (+) operators, passes basic unittests
+
+ .. change::
+ :tags:
+ :tickets:
+
+ tweaks to Oracle LIMIT/OFFSET support
+
+ .. change::
+ :tags:
+ :tickets:
+
+ Oracle reflection uses ALL_** views instead of USER_** to get larger
+ list of stuff to reflect from
+
+ .. change::
+ :tags:
+ :tickets: 105
+
+ fixes to Oracle foreign key reflection
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ some minor speed improvements to the attributes system with regards to
+ instantiating and populating new objects.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ fixed MySQL binary unit test
+
+ .. change::
+ :tags:
+ :tickets:
+
+ INSERTs can receive clause elements as VALUES arguments, not just literal
+ values
+
+ .. change::
+ :tags:
+ :tickets:
+
+ support for calling multi-tokened functions, i.e. schema.mypkg.func()
+
+ .. change::
+ :tags:
+ :tickets:
+
+ added J. Ellis' SQLSoup module to extensions package
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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
+
+ .. change::
+ :tags:
+ :tickets:
+
+ improvements/fixes to session.refresh()/session.expire() (which may have
+ been called "invalidate" earlier..)
+
+ .. change::
+ :tags:
+ :tickets:
+
+ added session.expunge() which totally removes an object from the current
+ session
+
+ .. change::
+ :tags:
+ :tickets:
+
+ added *args, **kwargs pass-thru to engine.transaction(func) allowing easier
+ creation of transactionalizing decorator functions
+
+ .. change::
+ :tags:
+ :tickets:
+
+ added iterator interface to ResultProxy: "for row in result:..."
+
+ .. change::
+ :tags:
+ :tickets:
+
+ added assertion to tx = session.begin(); tx.rollback(); tx.begin(), i.e. cant
+ use it after a rollback()
+
+ .. change::
+ :tags:
+ :tickets:
+
+ added date conversion on bind parameter fix to SQLite enabling dates to
+ work with pysqlite1
+
+ .. change::
+ :tags:
+ :tickets: 116
+
+ improvements to subqueries to more intelligently construct their FROM
+ clauses
+
+ .. change::
+ :tags:
+ :tickets:
+
+ added PickleType to types.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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
+
+ .. change::
+ :tags:
+ :tickets:
+
+ major overhaul to unit of work documentation, other documentation sections.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ fixed attributes bug where if an object is committed, its lazy-loaded list got
+ blown away if it hadnt been loaded
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ added distinct() function to column elements so you can do
+ func.count(mycol.distinct())
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+.. changelog::
+ :version: 0.1.4
+ :released: Mon Mar 13 2006
+
+ .. change::
+ :tags:
+ :tickets:
+
+ create_engine() now uses genericized parameters; host/hostname,
+ db/dbname/database, password/passwd, etc. for all engine connections. makes
+ engine URIs much more "universal"
+
+ .. change::
+ :tags:
+ :tickets:
+
+ added support for SELECT statements embedded into a column clause, using the
+ flag "scalar=True"
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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
+
+ .. change::
+ :tags:
+ :tickets:
+
+ added onupdate parameter to Column, will exec SQL/python upon an update
+ statement.Also adds "for_update=True" to all DefaultGenerator subclasses
+
+ .. change::
+ :tags:
+ :tickets:
+
+ added support for Oracle table reflection contributed by Andrija Zaric;
+ still some bugs to work out regarding composite primary keys/dictionary selection
+
+ .. change::
+ :tags:
+ :tickets:
+
+ checked in an initial Firebird module, awaiting testing.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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
+
+ .. change::
+ :tags:
+ :tickets:
+
+ more docs for indexes, column defaults, connection pooling, engine construction
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ added "convert_unicode=False" parameter to SQLEngine, will cause all String
+ types to perform unicode encoding/decoding (makes Strings act like Unicodes)
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ improved support for mapping against UNIONs, added polymorph.py example
+ to illustrate multi-class mapping against a UNION
+
+ .. change::
+ :tags:
+ :tickets:
+
+ fix to SQLite LIMIT/OFFSET syntax
+
+ .. change::
+ :tags:
+ :tickets:
+
+ fix to Oracle LIMIT syntax
+
+ .. change::
+ :tags:
+ :tickets:
+
+ added backref() function, allows backreferences to have keyword arguments
+ that will be passed to the backref.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ Sequences and ColumnDefault objects can do execute()/scalar() standalone
+
+ .. change::
+ :tags:
+ :tickets:
+
+ SQL functions (i.e. func.foo()) can do execute()/scalar() standalone
+
+ .. change::
+ :tags:
+ :tickets:
+
+ fix to SQL functions so that the ANSI-standard functions, i.e. current_timestamp
+ etc., do not specify parenthesis. all other functions do.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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')
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ added 'get_session().invalidate(*obj)' method to objectstore, instances will
+ refresh() themselves upon the next attribute access.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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
+
+ .. change::
+ :tags:
+ :tickets:
+
+ fix to MySQL4 custom table engines, i.e. TYPE instead of ENGINE
+
+ .. change::
+ :tags:
+ :tickets:
+
+ slightly enhanced logging, includes timestamps and a somewhat configurable
+ formatting system, in lieu of a full-blown logging system
+
+ .. change::
+ :tags:
+ :tickets:
+
+ improvements to the ActiveMapper class from the TG gang, including
+ many-to-many relationships
+
+ .. change::
+ :tags:
+ :tickets:
+
+ added Double and TinyInt support to mysql
+
+.. changelog::
+ :version: 0.1.3
+ :released: Thu Mar 02 2006
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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
+
+ .. change::
+ :tags:
+ :tickets:
+
+ completed mapper.using(session) function, localized per-object Session
+ functionality; objects can be declared and manipulated as local to any
+ user-defined Session
+
+ .. change::
+ :tags:
+ :tickets:
+
+ fix to Oracle "row_number over" clause with multiple tables
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ made objectstore "check for out-of-identitymap" more aggressive, will perform the
+ check when object attributes are modified or the object is deleted
+
+ .. change::
+ :tags:
+ :tickets:
+
+ Index object fully implemented, can be constructed standalone, or via
+ "index" and "unique" arguments on Columns.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ postgres maintains a list of ANSI functions that must have no parenthesis so
+ function calls with no arguments work consistently
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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".
+
+ .. change::
+ :tags:
+ :tickets:
+
+ added "refresh(*obj)" method to objectstore / Session to reload the attributes of
+ any set of objects from the database unconditionally
+
+.. changelog::
+ :version: 0.1.2
+ :released: Fri Feb 24 2006
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+.. changelog::
+ :version: 0.1.1
+ :released: Thu Feb 23 2006
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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).
+
+ .. change::
+ :tags:
+ :tickets:
+
+ creating self-referring mappers with backrefs slightly easier (but still not that easy -
+ changeset 1019)
+
+ .. change::
+ :tags:
+ :tickets:
+
+ fixes to one-to-one mappings (changeset 1015)
+
+ .. change::
+ :tags:
+ :tickets:
+
+ psycopg1 date/time issue with None fixed (changeset 1005)
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ fixed a glitch with engine.execute_compiled where it was making a second
+ ResultProxy that just got thrown away.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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']
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ added exceptions module, all raised exceptions (except for some
+ KeyError/AttributeError exceptions) descend from these classes.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ fix to date types with MySQL, returned timedelta converted to datetime.time
+
+ .. change::
+ :tags:
+ :tickets:
+
+ two-phase objectstore.commit operations (i.e. begin/commit) now return a
+ transactional object (SessionTrans), to more clearly indicate transaction boundaries.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ Index object with create/drop support added to schema
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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::
+ :tags:
+ :tickets:
+
+ 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
+
+ .. change::
+ :tags:
+ :tickets:
+
+ fix to engine.process_defaults so it works correctly with a table that has
+ different column name/column keys (changset 982)
+
+ .. change::
+ :tags:
+ :tickets:
+
+ a column can only be attached to one table - this is now asserted
+
+ .. change::
+ :tags:
+ :tickets:
+
+ postgres time types descend from Time type
+
+ .. change::
+ :tags:
+ :tickets:
+
+ fix to alltests so that it runs types test (now named testtypes)
+
+ .. change::
+ :tags:
+ :tickets:
+
+ fix to Join object so that it correctly exports its foreign keys (cs 973)
+
+ .. change::
+ :tags:
+ :tickets:
+
+ creating relationships against mappers that use inheritance fixed (cs 973)
--- /dev/null
+
+==============
+0.2 Changelog
+==============
+
+
+.. changelog::
+ :version: 0.2.8
+ :released: Tue Sep 05 2006
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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'.
+
+ .. change::
+ :tags:
+ :tickets: 274
+
+ 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
+
+ .. change::
+ :tags:
+ :tickets: 121
+
+ 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
+
+ .. change::
+ :tags:
+ :tickets:
+
+ eesh ! the tutorial doctest was broken for quite some time.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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 !)
+
+ .. change::
+ :tags:
+ :tickets: 277
+
+ check for pg sequence already existing before create
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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)
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ it is now invalid to declare a self-referential relationship with
+ "delete-orphan" (as the abovementioned check would make them impossible
+ to save)
+
+ .. change::
+ :tags:
+ :tickets:
+
+ improved the check for objects being part of a session when the
+ unit of work seeks to flush() them as part of a relationship..
+
+ .. change::
+ :tags:
+ :tickets: 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.
+
+ .. change::
+ :tags:
+ :tickets: 60, 71
+
+ postgres reflection moved to use pg_schema tables, can be overridden
+ with use_information_schema=True argument to create_engine.
+
+ .. change::
+ :tags:
+ :tickets: 155
+
+ 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
+
+ .. change::
+ :tags:
+ :tickets:
+
+ unit tests updated to run without any pysqlite installed; pool
+ test uses a mock DBAPI
+
+ .. change::
+ :tags:
+ :tickets: 281
+
+ urls support escaped characters in passwords
+
+ .. change::
+ :tags:
+ :tickets:
+
+ added limit/offset to UNION queries (though not yet in oracle)
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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).
+
+ .. change::
+ :tags:
+ :tickets: 287
+
+ fix to using query.count() with distinct, **kwargs with SelectResults
+ count()
+
+ .. change::
+ :tags:
+ :tickets: 289
+
+ deregister Table from MetaData when autoload fails;
+
+ .. change::
+ :tags:
+ :tickets: 293
+
+ import of py2.5s sqlite3
+
+ .. change::
+ :tags:
+ :tickets: 296
+
+ unicode fix for startswith()/endswith()
+
+.. changelog::
+ :version: 0.2.7
+ :released: Sat Aug 12 2006
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ assignmapper was setting is_primary=True, causing all sorts of mayhem
+ by not raising an error when redundant mappers were set up, fixed
+
+ .. change::
+ :tags:
+ :tickets:
+
+ added allow_null_pks option to Mapper, allows rows where some
+ primary key columns are null (i.e. when mapping to outer joins etc)
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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)
+
+ .. change::
+ :tags:
+ :tickets:
+
+ fixed reflection of foreign keys to autoload the referenced table
+ if it was not loaded already
+
+ .. change::
+ :tags:
+ :tickets: 256
+
+ - pass URL query string arguments to connect() function
+
+ .. change::
+ :tags:
+ :tickets: 257
+
+ - oracle boolean type
+
+ .. change::
+ :tags:
+ :tickets:
+
+ custom primary/secondary join conditions in a relation *will* be propagated
+ to backrefs by default. specifying a backref() will override this behavior.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ sqlite creates ForeignKeyConstraint objects properly upon table
+ reflection.
+
+ .. change::
+ :tags:
+ :tickets: 224
+
+ adjustments to pool stemming from changes made for.
+ overflow counter should only be decremented if the connection actually
+ succeeded. added a test script to attempt testing this.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ fixed mysql reflection of default values to be PassiveDefault
+
+ .. change::
+ :tags:
+ :tickets: 263, 264
+
+ added reflected 'tinyint', 'mediumint' type to MS-SQL.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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)
+
+ .. change::
+ :tags:
+ :tickets: 267, 265
+
+ fixed small pickle bug(s) with lazy loaders
+
+ .. change::
+ :tags:
+ :tickets:
+
+ fixed possible error in mysql reflection where certain versions
+ return an array instead of string for SHOW CREATE TABLE call
+
+ .. change::
+ :tags:
+ :tickets: 1770
+
+ fix to lazy loads when mapping to joins
+
+ .. change::
+ :tags:
+ :tickets:
+
+ all create()/drop() calls have a keyword argument of "connectable".
+ "engine" is deprecated.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ fixed ms-sql connect() to work with adodbapi
+
+ .. change::
+ :tags:
+ :tickets:
+
+ added "nowait" flag to Select()
+
+ .. change::
+ :tags:
+ :tickets: 271
+
+ 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
+
+ .. change::
+ :tags:
+ :tickets: 252
+
+ SelectResults will use a subselect, when calling an aggregate (i.e.
+ max, min, etc.) on a SelectResults that has an ORDER BY clause
+
+ .. change::
+ :tags:
+ :tickets: 269
+
+ fixes to types so that database-specific types more easily used;
+ fixes to mysql text types to work with this methodology
+
+ .. change::
+ :tags:
+ :tickets:
+
+ some fixes to sqlite date type organization
+
+ .. change::
+ :tags:
+ :tickets: 263
+
+ added MSTinyInteger to MS-SQL
+
+.. changelog::
+ :version: 0.2.6
+ :released: Thu Jul 20 2006
+
+ .. change::
+ :tags:
+ :tickets: 76
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ overhaul to MapperExtension calling scheme, wasnt working very well
+ previously
+
+ .. change::
+ :tags:
+ :tickets:
+
+ tweaks to ActiveMapper, supports self-referential relationships
+
+ .. change::
+ :tags:
+ :tickets:
+
+ slight rearrangement to objectstore (in activemapper/threadlocal)
+ so that the SessionContext is referenced by '.context' instead
+ of subclassed directly.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ activemapper will use threadlocal's objectstore if the mod is
+ activated when activemapper is imported
+
+ .. change::
+ :tags:
+ :tickets:
+
+ small fix to URL regexp to allow filenames with '@' in them
+
+ .. change::
+ :tags:
+ :tickets:
+
+ fixes to Session expunge/update/etc...needs more cleanup.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ select_table mappers *still* werent always compiling
+
+ .. change::
+ :tags:
+ :tickets:
+
+ fixed up Boolean datatype
+
+ .. change::
+ :tags:
+ :tickets:
+
+ added count()/count_by() to list of methods proxied by assignmapper;
+ this also adds them to activemapper
+
+ .. change::
+ :tags:
+ :tickets:
+
+ connection exceptions wrapped in DBAPIError
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ deferred column load could screw up the connection status in
+ a flush() under some circumstances, this was fixed
+
+ .. change::
+ :tags:
+ :tickets:
+
+ expunge() was not working with cascade, fixed.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ potential endless loop in cascading operations fixed.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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().
+
+ .. change::
+ :tags:
+ :tickets:
+
+ fix to typing in clause construction which specifically helps
+ type issues with polymorphic_union (CAST/ColumnClause propagates
+ its type to proxy columns)
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ eager loads explicitly disallowed on self-referential relationships, or
+ relationships to an inheriting mapper (which is also self-referential)
+
+ .. change::
+ :tags:
+ :tickets: 244
+
+ reduced bind param size in query._get to appease the picky oracle
+
+ .. change::
+ :tags:
+ :tickets: 234
+
+ added 'checkfirst' argument to table.create()/table.drop(), as
+ well as table.exists()
+
+ .. change::
+ :tags:
+ :tickets: 245
+
+ some other ongoing fixes to inheritance
+
+ .. change::
+ :tags:
+ :tickets:
+
+ attribute/backref/orphan/history-tracking tweaks as usual...
+
+.. changelog::
+ :version: 0.2.5
+ :released: Sat Jul 08 2006
+
+ .. change::
+ :tags:
+ :tickets:
+
+ fixed endless loop bug in select_by(), if the traversal hit
+ two mappers that referenced each other
+
+ .. change::
+ :tags:
+ :tickets:
+
+ upgraded all unittests to insert './lib/' into sys.path,
+ working around new setuptools PYTHONPATH-killing behavior
+
+ .. change::
+ :tags:
+ :tickets:
+
+ further fixes with attributes/dependencies/etc....
+
+ .. change::
+ :tags:
+ :tickets:
+
+ improved error handling for when DynamicMetaData is not connected
+
+ .. change::
+ :tags:
+ :tickets:
+
+ MS-SQL support largely working (tested with pymssql)
+
+ .. change::
+ :tags:
+ :tickets:
+
+ ordering of UPDATE and DELETE statements within groups is now
+ in order of primary key values, for more deterministic ordering
+
+ .. change::
+ :tags:
+ :tickets:
+
+ after_insert/delete/update mapper extensions now called per object,
+ not per-object-per-table
+
+ .. change::
+ :tags:
+ :tickets:
+
+ further fixes/refactorings to mapper compilation
+
+.. changelog::
+ :version: 0.2.4
+ :released: Tue Jun 27 2006
+
+ .. change::
+ :tags:
+ :tickets:
+
+ try/except when the mapper sets init.__name__ on a mapped class,
+ supports python 2.3
+
+ .. change::
+ :tags:
+ :tickets:
+
+ fixed bug where threadlocal engine would still autocommit
+ despite a transaction in progress
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ fixes to mapper compilation, checking for more error conditions
+
+ .. change::
+ :tags:
+ :tickets:
+
+ small fix to eager loading combined with ordering/limit/offset
+
+ .. change::
+ :tags:
+ :tickets: 206
+
+ utterly remarkable: added a single space between 'CREATE TABLE'
+ and '(<the rest of it>' since *thats how MySQL indicates a non-
+ reserved word tablename.....*
+
+ .. change::
+ :tags:
+ :tickets:
+
+ more fixes to inheritance, related to many-to-many relations
+ properly saving
+
+ .. change::
+ :tags:
+ :tickets:
+
+ fixed bug when specifying explicit module to mysql dialect
+
+ .. change::
+ :tags:
+ :tickets:
+
+ when QueuePool times out it raises a TimeoutError instead of
+ erroneously making another connection
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ postgres will not place SERIAL keyword on a primary key column
+ if it has a foreign key constraint
+
+ .. change::
+ :tags:
+ :tickets: 221
+
+ cursor() method on ConnectionFairy allows db-specific extension
+ arguments to be propagated
+
+ .. change::
+ :tags:
+ :tickets: 225
+
+ lazy load bind params properly propagate column type
+
+ .. change::
+ :tags:
+ :tickets:
+
+ new MySQL types: MSEnum, MSTinyText, MSMediumText, MSLongText, etc.
+ more support for MS-specific length/precision params in numeric types
+ patch courtesy Mike Bernson
+
+ .. change::
+ :tags:
+ :tickets: 224
+
+ some fixes to connection pool invalidate()
+
+.. changelog::
+ :version: 0.2.3
+ :released: Sat Jun 17 2006
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ fixed a pretty big speed bottleneck in cascading behavior particularly
+ when backrefs were in use
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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).
+
+ .. change::
+ :tags:
+ :tickets:
+
+ py2.4 "set" construct used internally, falls back to sets.Set when
+ "set" not available/ordering is needed.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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)
+
+ .. change::
+ :tags:
+ :tickets: 151
+
+ "foreignkey" argument to relation() can also be a list. fixed
+ auto-foreignkey detection
+
+ .. change::
+ :tags:
+ :tickets:
+
+ fixed bug where tables with schema names werent getting indexed in
+ the MetaData object properly
+
+ .. change::
+ :tags:
+ :tickets: 207
+
+ fixed bug where Column with redefined "key" property wasnt getting
+ type conversion happening in the ResultProxy
+
+ .. change::
+ :tags:
+ :tickets:
+
+ fixed 'port' attribute of URL to be an integer if present
+
+ .. change::
+ :tags:
+ :tickets:
+
+ fixed old bug where if a many-to-many table mapped as "secondary"
+ had extra columns, delete operations didnt work
+
+ .. change::
+ :tags:
+ :tickets:
+
+ bugfixes for mapping against UNION queries
+
+ .. change::
+ :tags:
+ :tickets:
+
+ fixed incorrect exception class thrown when no DB driver present
+
+ .. change::
+ :tags:
+ :tickets: 138
+
+ added NonExistentTable exception thrown when reflecting a table
+ that doesnt exist
+
+ .. change::
+ :tags:
+ :tickets:
+
+ small fix to ActiveMapper regarding one-to-one backrefs, other
+ refactorings
+
+ .. change::
+ :tags:
+ :tickets:
+
+ overridden constructor in mapped classes gets __name__ and
+ __doc__ from the original class
+
+ .. change::
+ :tags:
+ :tickets: 200
+
+ fixed small bug in selectresult.py regarding mapper extension
+
+ .. change::
+ :tags:
+ :tickets:
+
+ small tweak to cascade_mappers, not very strongly supported
+ function at the moment
+
+ .. change::
+ :tags:
+ :tickets: 202
+
+ some fixes to between(), column.between() to propagate typing
+ information better
+
+ .. change::
+ :tags:
+ :tickets: 203
+
+ if an object fails to be constructed, is not added to the
+ session
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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
+
+.. changelog::
+ :version: 0.2.2
+ :released: Mon Jun 05 2006
+
+ .. change::
+ :tags:
+ :tickets: 190
+
+ big improvements to polymorphic inheritance behavior, enabling it
+ to work with adjacency list table structures
+
+ .. change::
+ :tags:
+ :tickets:
+
+ major fixes and refactorings to inheritance relationships overall,
+ more unit tests
+
+ .. change::
+ :tags:
+ :tickets:
+
+ fixed "echo_pool" flag on create_engine()
+
+ .. change::
+ :tags:
+ :tickets:
+
+ fix to docs, removed incorrect info that close() is unsafe to use
+ with threadlocal strategy (its totally safe !)
+
+ .. change::
+ :tags:
+ :tickets: 188
+
+ create_engine() can take URLs as string or unicode
+
+ .. change::
+ :tags:
+ :tickets:
+
+ firebird support partially completed;
+ thanks to James Ralston and Brad Clements for their efforts.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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
+
+ .. change::
+ :tags:
+ :tickets:
+
+ fix to using unicode criterion for query.get()/query.load()
+
+ .. change::
+ :tags:
+ :tickets:
+
+ count() function on selectables now uses table primary key or
+ first column instead of "1" for criterion, also uses label "rowcount"
+ instead of "count".
+
+ .. change::
+ :tags:
+ :tickets:
+
+ got rudimental "mapping to multiple tables" functionality cleaned up,
+ more correctly documented
+
+ .. change::
+ :tags:
+ :tickets:
+
+ restored global_connect() function, attaches to a DynamicMetaData
+ instance called "default_metadata". leaving MetaData arg to Table
+ out will use the default metadata.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ fixes to session cascade behavior, entity_name propigation
+
+ .. change::
+ :tags:
+ :tickets:
+
+ reorganized unittests into subdirectories
+
+ .. change::
+ :tags:
+ :tickets:
+
+ more fixes to threadlocal connection nesting patterns
+
+.. changelog::
+ :version: 0.2.1
+ :released: Mon May 29 2006
+
+ .. change::
+ :tags:
+ :tickets:
+
+ "pool" argument to create_engine() properly propagates
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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)
+
+ .. change::
+ :tags:
+ :tickets:
+
+ small fixes to Mapper when it inserts and tries to get
+ new primary key values back
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ placeholder dispose() method added to SingletonThreadPool, doesnt
+ do anything yet
+
+ .. change::
+ :tags:
+ :tickets:
+
+ rollback() is automatically called when an exception is raised,
+ but only if theres no transaction in process (i.e. works more like
+ autocommit).
+
+ .. change::
+ :tags:
+ :tickets:
+
+ fixed exception raise in sqlite if no sqlite module present
+
+ .. change::
+ :tags:
+ :tickets:
+
+ added extra example detail for association object doc
+
+ .. change::
+ :tags:
+ :tickets:
+
+ Connection adds checks for already being closed
+
+.. changelog::
+ :version: 0.2.0
+ :released: Sat May 27 2006
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ create_engine now takes only RFC-1738-style strings:
+ driver://user:password@host:port/database
+
+ .. change::
+ :tags:
+ :tickets: 152
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets: 167
+
+ true polymorphic behavior implemented, fixes
+
+ .. change::
+ :tags:
+ :tickets: 147
+
+ "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
+
+ .. change::
+ :tags:
+ :tickets:
+
+ overhaul to packaging; "mapping" is now "orm", "objectstore" is now
+ "session", the old "objectstore" namespace gets loaded in via the
+ "threadlocal" mod if used
+
+ .. change::
+ :tags:
+ :tickets:
+
+ mods now called in via "import <modname>". extensions favored over
+ mods as mods are globally-monkeypatching
+
+ .. change::
+ :tags:
+ :tickets: 154
+
+ fix to add_property so that it propagates properties to inheriting
+ mappers
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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
+
+ .. change::
+ :tags:
+ :tickets: 31
+
+ "table exists" function has been implemented
+
+ .. change::
+ :tags:
+ :tickets: 98
+
+ "create_all/drop_all" added to MetaData object
+
+ .. change::
+ :tags:
+ :tickets:
+
+ improvements and fixes to topological sort algorithm, as well as more
+ unit tests
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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
+
+ .. change::
+ :tags:
+ :tickets:
+
+ many more fixes, refactorings.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ migration guide is available on the Wiki at
+ http://www.sqlalchemy.org/trac/wiki/02Migration
--- /dev/null
+
+==============
+0.3 Changelog
+==============
+
+
+.. changelog::
+ :version: 0.3.11
+ :released: Sun Oct 14 2007
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ tweak DISTINCT precedence for clauses like
+ `func.count(t.c.col.distinct())`
+
+ .. change::
+ :tags: sql
+ :tickets: 719
+
+ Fixed detection of internal '$' characters in :bind$params
+
+ .. change::
+ :tags: sql
+ :tickets: 768
+
+ dont assume join criterion consists only of column objects
+
+ .. change::
+ :tags: sql
+ :tickets: 764
+
+ 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")
+
+ .. change::
+ :tags: orm
+ :tickets: 687
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ fixed small exception throw bug in Session.merge()
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets: 769
+
+ fixed bugs in determining proper sync clauses from custom inherit
+ conditions
+
+ .. change::
+ :tags: orm
+ :tickets: 813
+
+ backref remove object operation doesn't fail if the other-side
+ collection doesn't contain the item, supports noload collections
+
+ .. change::
+ :tags: engine
+ :tickets:
+
+ fixed another occasional race condition which could occur
+ when using pool with threadlocal setting
+
+ .. change::
+ :tags: mysql
+ :tickets:
+
+ fixed specification of YEAR columns when generating schema
+
+ .. change::
+ :tags: mssql
+ :tickets: 679
+
+ added support for TIME columns (simulated using DATETIME)
+
+ .. change::
+ :tags: mssql
+ :tickets: 721
+
+ added support for BIGINT, MONEY, SMALLMONEY, UNIQUEIDENTIFIER and
+ SQL_VARIANT
+
+ .. change::
+ :tags: mssql
+ :tickets: 684
+
+ index names are now quoted when dropping from reflected tables
+
+ .. change::
+ :tags: mssql
+ :tickets:
+
+ can now specify a DSN for PyODBC, using a URI like mssql:///?dsn=bob
+
+ .. change::
+ :tags: postgres
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: sqlite
+ :tickets:
+
+ passthrough for stringified dates
+
+ .. change::
+ :tags: firebird
+ :tickets:
+
+ supports_sane_rowcount() set to False due to ticket #370 (right way).
+
+ .. change::
+ :tags: firebird
+ :tickets:
+
+ fixed reflection of Column's nullable property.
+
+ .. change::
+ :tags: oracle
+ :tickets: 622, 751
+
+ removed LONG_STRING, LONG_BINARY from "binary" types, so type objects
+ don't try to read their values as LOB.
+
+.. changelog::
+ :version: 0.3.10
+ :released: Fri Jul 20 2007
+
+ .. change::
+ :tags: general
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ got connection-bound metadata to work with implicit execution
+
+ .. change::
+ :tags: sql
+ :tickets: 667
+
+ foreign key specs can have any chararcter in their identifiers
+
+ .. change::
+ :tags: sql
+ :tickets: 664
+
+ added commutativity-awareness to binary clause comparisons to
+ each other, improves ORM lazy load optimization
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ cleanup to connection-bound sessions, SessionTransaction
+
+ .. change::
+ :tags: postgres
+ :tickets: 571
+
+ fixed max identifier length (63)
+
+.. changelog::
+ :version: 0.3.9
+ :released: Sun Jul 15 2007
+
+ .. change::
+ :tags: general
+ :tickets: 607
+
+ better error message for NoSuchColumnError
+
+ .. change::
+ :tags: general
+ :tickets: 428
+
+ finally figured out how to get setuptools version in, available
+ as sqlalchemy.__version__
+
+ .. change::
+ :tags: general
+ :tickets:
+
+ 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>
+
+ .. change::
+ :tags: ext
+ :tickets:
+
+ iteration over dict association proxies is now dict-like, not
+ InstrumentedList-like (e.g. over keys instead of values)
+
+ .. change::
+ :tags: ext
+ :tickets: 597
+
+ association proxies no longer bind tightly to source collections, and are constructed with a thunk instead
+
+ .. change::
+ :tags: ext
+ :tickets:
+
+ added selectone_by() to assignmapper
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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"
+
+ .. change::
+ :tags: orm
+ :tickets: 613
+
+ added synchronization to the mapper() construction step, to avoid
+ thread collisions when pre-existing mappers are compiling in a
+ different thread
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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).
+
+ .. change::
+ :tags: orm
+ :tickets: 598
+
+ synonym() properties are fully supported by all Query joining/
+ with_parent operations
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ fixed very stupid bug when deleting items with many-to-many
+ uselist=False relations
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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).
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ small fix to eager loading to better work with eager loads
+ to polymorphic mappers that are using a straight "outerjoin"
+ clause
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ 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')
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ MetaData can now be constructed with an engine or url as the first
+ argument, just like BoundMetaData
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ BoundMetaData is now deprecated, and MetaData is a direct substitute.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ DynamicMetaData has been renamed to ThreadLocalMetaData. the
+ DynamicMetaData name is deprecated and is an alias for ThreadLocalMetaData
+ or a regular MetaData if threadlocal=False
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: sql
+ :tickets: 185
+
+ 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.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ added 'bind' argument to Sequence.create()/drop(), ColumnDefault.execute()
+
+ .. change::
+ :tags: sql
+ :tickets: 650
+
+ columns can be overridden in a reflected table with a "key"
+ attribute different than the column's name, including for primary key
+ columns
+
+ .. change::
+ :tags: sql
+ :tickets: 657
+
+ fixed "ambiguous column" result detection, when dupe col names exist
+ in a result
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ 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
+
+ .. change::
+ :tags: sql
+ :tickets: 619
+
+ 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.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ added a mutex to QueuePool's "overflow" calculation to prevent a race
+ condition that can bypass max_overflow
+
+ .. change::
+ :tags: sql
+ :tickets: 623
+
+ 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
+
+ .. change::
+ :tags: sql
+ :tickets: 620
+
+ fixed precedence of operators so that parenthesis are correctly applied
+
+ .. change::
+ :tags: sql
+ :tickets: 545
+
+ 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
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ fixed "where"/"from" criterion of select() to accept a unicode string
+ in addition to regular string - both convert to text()
+
+ .. change::
+ :tags: sql
+ :tickets: 558
+
+ added standalone distinct() function in addition to column.distinct()
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: sql
+ :tickets: 589
+
+ long-identifier detection fixed to use > rather than >= for
+ max ident length
+
+ .. change::
+ :tags: sql
+ :tickets: 593
+
+ 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
+
+ .. change::
+ :tags: sql
+ :tickets: 595
+
+ added Interval type to types.py
+
+ .. change::
+ :tags: mysql
+ :tickets: 625
+
+ fixed catching of some errors that imply a dropped connection
+
+ .. change::
+ :tags: mysql
+ :tickets: 624
+
+ fixed escaping of the modulo operator
+
+ .. change::
+ :tags: mysql
+ :tickets: 590
+
+ added 'fields' to reserved words
+
+ .. change::
+ :tags: mysql
+ :tickets:
+
+ various reflection enhancement/fixes
+
+ .. change::
+ :tags: oracle
+ :tickets: 604
+
+ datetime fixes: got subsecond TIMESTAMP to work,
+ added OracleDate which supports types.Date with only year/month/day
+
+ .. change::
+ :tags: oracle
+ :tickets:
+
+ 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).
+
+ .. change::
+ :tags: oracle
+ :tickets: 624
+
+ mod operator '%' produces MOD
+
+ .. change::
+ :tags: oracle
+ :tickets: 542
+
+ converts cx_oracle datetime objects to Python datetime.datetime when
+ Python 2.3 used
+
+ .. change::
+ :tags: oracle
+ :tickets:
+
+ fixed unicode conversion in Oracle TEXT type
+
+ .. change::
+ :tags: postgres
+ :tickets: 624
+
+ fixed escaping of the modulo operator
+
+ .. change::
+ :tags: postgres
+ :tickets: 570
+
+ added support for reflection of domains
+
+ .. change::
+ :tags: postgres
+ :tickets:
+
+ types which are missing during reflection resolve to Null type
+ instead of raising an error
+
+ .. change::
+ :tags: postgres
+ :tickets:
+
+ the fix in "schema" above fixes reflection of foreign keys from an
+ alt-schema table to a public schema table
+
+ .. change::
+ :tags: sqlite
+ :tickets:
+
+ rearranged dialect initialization so it has time to warn about pysqlite1
+ being too old.
+
+ .. change::
+ :tags: sqlite
+ :tickets:
+
+ sqlite better handles datetime/date/time objects mixed and matched
+ with various Date/Time/DateTime columns
+
+ .. change::
+ :tags: sqlite
+ :tickets: 603
+
+ string PK column inserts dont get overwritten with OID
+
+ .. change::
+ :tags: mssql
+ :tickets: 634
+
+ fix port option handling for pyodbc
+
+ .. change::
+ :tags: mssql
+ :tickets:
+
+ now able to reflect start and increment values for identity columns
+
+ .. change::
+ :tags: mssql
+ :tickets:
+
+ preliminary support for using scope_identity() with pyodbc
+
+.. changelog::
+ :version: 0.3.8
+ :released: Sat Jun 02 2007
+
+ .. change::
+ :tags: engines
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: engines
+ :tickets:
+
+ added invalidate() to Connection, immediately invalidates the
+ Connection and its underlying DBAPI connection.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ _Label class overrides compare_self to return its ultimate
+ object. meaning, if you say someexpr.label('foo') == 5, it
+ produces the correct "someexpr == 5".
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ _Label propagates "_hide_froms()" so that scalar selects
+ behave more properly with regards to FROM clause #574
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ fix to long name generation when using oid_column as an order by
+ (oids used heavily in mapper queries)
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ significant speed improvement to ResultProxy, pre-caches
+ TypeEngine dialect implementations and saves on function calls
+ per column
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ 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)
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ added 'modifier' keyword, works like func.<foo> except does not
+ add parenthesis. e.g. select([modifier.DISTINCT(...)]) etc.
+
+ .. change::
+ :tags: sql
+ :tickets: 578
+
+ removed "no group by's in a select thats part of a UNION"
+ restriction
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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']).
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ fixed bug in query.instances() that wouldnt handle more than
+ on additional mapper or one additional column.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ "delete-orphan" no longer implies "delete". ongoing effort to
+ separate the behavior of these two operations.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ many-to-many relationships properly set the type of bind params
+ for delete operations on the association table
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ many-to-many relationships check that the number of rows deleted
+ from the association table by a delete operation matches the
+ expected results
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ session.get() and session.load() propagate **kwargs through to
+ query
+
+ .. change::
+ :tags: orm
+ :tickets: 577
+
+ fix to polymorphic query which allows the original
+ polymorphic_union to be embedded into a correlated subquery
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ fix to select_by(<propname>=<object instance>) -style joins in
+ conjunction with many-to-many relationships, bug introduced in
+ r2556
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ restored logging of "lazy loading clause" under
+ sa.orm.strategies logger, got removed in 0.3.7
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: mysql
+ :tickets:
+
+ Nearly all MySQL column types are now supported for declaration
+ and reflection. Added NCHAR, NVARCHAR, VARBINARY, TINYBLOB,
+ LONGBLOB, YEAR
+
+ .. change::
+ :tags: mysql
+ :tickets:
+
+ The sqltypes.Binary passthrough now always builds a BLOB,
+ avoiding problems with very old database versions
+
+ .. change::
+ :tags: mysql
+ :tickets:
+
+ support for column-level CHARACTER SET and COLLATE declarations,
+ as well as ASCII, UNICODE, NATIONAL and BINARY shorthand.
+
+ .. change::
+ :tags: firebird
+ :tickets:
+
+ set max identifier length to 31
+
+ .. change::
+ :tags: firebird
+ :tickets:
+
+ supports_sane_rowcount() set to False due to ticket #370.
+ versioned_id_col feature wont work in FB.
+
+ .. change::
+ :tags: firebird
+ :tickets:
+
+ some execution fixes
+
+ .. change::
+ :tags: firebird
+ :tickets:
+
+ new association proxy implementation, implementing complete
+ proxies to list, dict and set-based relation collections
+
+ .. change::
+ :tags: firebird
+ :tickets:
+
+ added orderinglist, a custom list class that synchronizes an
+ object attribute with that object's position in the list
+
+ .. change::
+ :tags: firebird
+ :tickets:
+
+ small fix to SelectResultsExt to not bypass itself during
+ select().
+
+ .. change::
+ :tags: firebird
+ :tickets:
+
+ added filter(), filter_by() to assignmapper
+
+.. changelog::
+ :version: 0.3.7
+ :released: Sun Apr 29 2007
+
+ .. change::
+ :tags: engines
+ :tickets:
+
+ warnings module used for issuing warnings (instead of logging)
+
+ .. change::
+ :tags: engines
+ :tickets: 480
+
+ cleanup of DBAPI import strategies across all engines
+
+ .. change::
+ :tags: engines
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: engines
+ :tickets: 514
+
+ server side cursor support fully functional in postgres.
+
+ .. change::
+ :tags: engines
+ :tickets:
+
+ 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
+
+ .. change::
+ :tags: engines
+ :tickets: 521
+
+ 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
+
+ .. change::
+ :tags: engines
+ :tickets:
+
+ Engine contains a "url" attribute referencing the url.URL object
+ used by create_engine().
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: sql
+ :tickets: 522
+
+ 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.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ ClauseElements can be used in in_() clauses now, such as bind
+ parameters, etc. #476
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ reverse operators implemented for `CompareMixin` elements,
+ allows expressions like "5 + somecolumn" etc. #474
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ 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().
+
+ .. change::
+ :tags: sql
+ :tickets: 512
+
+ 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.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: sql
+ :tickets: 513
+
+ 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)
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: sql
+ :tickets: 513
+
+ MS-SQL better detects when a query is a subquery and knows not to
+ generate ORDER BY phrases for those
+
+ .. change::
+ :tags: sql
+ :tickets: 505
+
+ fix for fetchmany() "size" argument being positional in most
+ dbapis
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ sending None as an argument to func.<something> will produce
+ an argument of NULL
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ query strings in unicode URLs get keys encoded to ascii
+ for **kwargs compat
+
+ .. change::
+ :tags: sql
+ :tickets: 523
+
+ slight tweak to raw execute() change to also support tuples
+ for positional parameters, not just lists
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ fix to case() construct to propagate the type of the first
+ WHEN condition as the return type of the case statement
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets: 541
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets: 554
+
+ 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
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ added generative versions of aggregates, i.e. sum(), avg(), etc.
+ to query. used via query.apply_max(), apply_sum(), etc.
+ #552
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ fix to using distinct() or distinct=True in combination with
+ join() and similar
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ corresponding to label/bindparam name generation, eager loaders
+ generate deterministic names for the aliases they create using
+ md5 hashes.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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)
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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).
+
+ .. change::
+ :tags: orm
+ :tickets: 533
+
+ fix to many-to-many relationships targeting polymorphic mappers
+
+ .. change::
+ :tags: orm
+ :tickets: 543
+
+ making progress with session.merge() as well as combining its
+ usage with entity_name
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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
+
+ .. change::
+ :tags: informix
+ :tickets:
+
+ informix support added ! courtesy James Zhang, who put a ton
+ of effort in.
+
+ .. change::
+ :tags: sqlite
+ :tickets:
+
+ removed silly behavior where sqlite would reflect UNIQUE indexes
+ as part of the primary key (?!)
+
+ .. change::
+ :tags: oracle
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: mysql
+ :tickets:
+
+ support for SSL arguments given as inline within URL query string,
+ prefixed with "ssl_", courtesy terjeros@gmail.com.
+
+ .. change::
+ :tags: <schemaname>, mysql
+ :tickets:
+
+ mysql uses "DESCRIBE.<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)
+
+ .. change::
+ :tags: extensions
+ :tickets:
+
+ big fix to AssociationProxy so that multiple AssociationProxy
+ objects can be associated with a single association collection.
+
+ .. change::
+ :tags: extensions
+ :tickets:
+
+ assign_mapper names methods according to their keys (i.e. __name__)
+ #551
+
+ .. change::
+ :tags: mssql
+ :tickets:
+
+ pyodbc is now the preferred DB-API for MSSQL, and if no module is
+ specifically requested, will be loaded first on a module probe.
+
+ .. change::
+ :tags: mssql
+ :tickets:
+
+ 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.
+
+.. changelog::
+ :version: 0.3.6
+ :released: Fri Mar 23 2007
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ slightly better support for bind params as column clauses, either
+ via bindparam() or via literal(), i.e. select([literal('foo')])
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ exists() becomes useable as a standalone selectable, not just in a
+ WHERE clause, i.e. exists([columns], criterion).select()
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ correlated subqueries work inside of ORDER BY, GROUP BY
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ fixed function execution with explicit connections, i.e.
+ conn.execute(func.dosomething())
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ 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")
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ 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").
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: sql
+ :tickets: 503
+
+ fixed use_alter flag on ForeignKeyConstraint
+
+ .. change::
+ :tags: sql
+ :tickets: 506
+
+ fixed usage of 2.4-only "reversed" in topological.py
+
+ .. change::
+ :tags: sql
+ :tickets: 501
+
+ 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).
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ the "else_" parameter to the case statement now properly works when
+ set to zero.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ strings and columns can also be sent to the *args of instances()
+ where those exact result columns will be part of the result tuples.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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().
+
+ .. change::
+ :tags: orm
+ :tickets: 495
+
+ 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. 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)
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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
+
+ .. change::
+ :tags: orm
+ :tickets: 249
+
+ many-to-many table will be properly handled even for operations that
+ occur on the "backref" side of the operation
+
+ .. change::
+ :tags: orm
+ :tickets: 492
+
+ added "refresh-expire" cascade. allows refresh() and
+ expire() calls to propagate along relationships.
+
+ .. change::
+ :tags: orm
+ :tickets: 493
+
+ more fixes to polymorphic relations, involving proper lazy-clause
+ generation on many-to-one relationships to polymorphic mappers. also fixes to detection of "direction", more specific
+ targeting of columns that belong to the polymorphic union vs. those
+ that dont.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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
+
+ .. change::
+ :tags: orm
+ :tickets: 500
+
+ 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") 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.
+
+ .. change::
+ :tags: extensions
+ :tickets: 472
+
+ options() method on SelectResults now implemented "generatively"
+ like the rest of the SelectResults methods. But
+ you're going to just use Query now anyway.
+
+ .. change::
+ :tags: extensions
+ :tickets:
+
+ query() method is added by assignmapper. this helps with
+ navigating to all the new generative methods on Query.
+
+ .. change::
+ :tags: ms-sql
+ :tickets:
+
+ removed seconds input on DATE column types (probably
+ should remove the time altogether)
+
+ .. change::
+ :tags: ms-sql
+ :tickets:
+
+ null values in float fields no longer raise errors
+
+ .. change::
+ :tags: ms-sql
+ :tickets:
+
+ LIMIT with OFFSET now raises an error (MS-SQL has no OFFSET support)
+
+ .. change::
+ :tags: ms-sql
+ :tickets: 509
+
+ 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.
+
+ .. change::
+ :tags: ms-sql
+ :tickets:
+
+ ORDER BY clauses without a LIMIT are now stripped in subqueries, as
+ MS-SQL forbids this usage
+
+ .. change::
+ :tags: ms-sql
+ :tickets: 480
+
+ cleanup of module importing code; specifiable DB-API module; more
+ explicit ordering of module preferences.
+
+ .. change::
+ :tags: oracle
+ :tickets:
+
+ 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).
+
+ .. change::
+ :tags: oracle
+ :tickets:
+
+ also fixed CLOB read/write on a separate changeset.
+
+ .. change::
+ :tags: oracle
+ :tickets:
+
+ auto_setinputsizes defaults to True for Oracle, fixed cases where
+ it improperly propagated bad types.
+
+ .. change::
+ :tags: mysql
+ :tickets:
+
+ added a catchall **kwargs to MSString, to help reflection of
+ obscure types (like "varchar() binary" in MS 4.0)
+
+ .. change::
+ :tags: mysql
+ :tickets:
+
+ added explicit MSTimeStamp type which takes effect when using
+ types.TIMESTAMP.
+
+.. changelog::
+ :version: 0.3.5
+ :released: Thu Feb 22 2007
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ 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
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ 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".
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ 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()
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ small fix to BoundMetaData to accept unicode or string URLs
+
+ .. change::
+ :tags: sql
+ :tickets: 466
+
+ fixed named PrimaryKeyConstraint generation courtesy
+ andrija at gmail
+
+ .. change::
+ :tags: sql
+ :tickets: 464
+
+ fixed generation of CHECK constraints on columns
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ fixes to tometadata() operation to propagate Constraints at column and
+ table level
+
+ .. change::
+ :tags: oracle
+ :tickets: 436
+
+ 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.
+
+ .. change::
+ :tags: oracle
+ :tickets:
+
+ sequences on a non-pk column will properly fire off on INSERT
+
+ .. change::
+ :tags: oracle
+ :tickets: 435
+
+ added PrefetchingResultProxy support to pre-fetch LOB columns when they
+ are known to be present, fixes
+
+ .. change::
+ :tags: oracle
+ :tickets: 379
+
+ implemented reflection of tables based on synonyms, including across
+ dblinks
+
+ .. change::
+ :tags: oracle
+ :tickets: 363
+
+ issues a log warning when a related table cant be reflected due to
+ certain permission errors
+
+ .. change::
+ :tags: mysql
+ :tickets:
+
+ fix to reflection on older DB's that might return array() type for
+ "show variables like" statements
+
+ .. change::
+ :tags: postgres
+ :tickets: 442
+
+ better reflection of sequences for alternate-schema Tables
+
+ .. change::
+ :tags: postgres
+ :tickets:
+
+ sequences on a non-pk column will properly fire off on INSERT
+
+ .. change::
+ :tags: postgres
+ :tickets: 460, 444
+
+ added PGInterval type, PGInet type
+
+ .. change::
+ :tags: mssql
+ :tickets: 419
+
+ preliminary support for pyodbc (Yay!)
+
+ .. change::
+ :tags: mssql
+ :tickets: 298
+
+ better support for NVARCHAR types added
+
+ .. change::
+ :tags: mssql
+ :tickets:
+
+ fix for commit logic on pymssql
+
+ .. change::
+ :tags: mssql
+ :tickets: 456
+
+ fix for query.get() with schema
+
+ .. change::
+ :tags: mssql
+ :tickets: 473
+
+ fix for non-integer relationships
+
+ .. change::
+ :tags: mssql
+ :tickets: 419
+
+ DB-API module now selectable at run-time
+
+ .. change::
+ :tags: tickets:422, 481, 415, mssql
+ :tickets:
+
+ now passes many more unit tests
+
+ .. change::
+ :tags: mssql
+ :tickets: 479
+
+ better unittest compatibility with ANSI functions
+
+ .. change::
+ :tags: mssql
+ :tickets: 415
+
+ improved support for implicit sequence PK columns with auto-insert
+
+ .. change::
+ :tags: mssql
+ :tickets: 371
+
+ fix for blank password in adodbapi
+
+ .. change::
+ :tags: mssql
+ :tickets: 481
+
+ fixes to get unit tests working with pyodbc
+
+ .. change::
+ :tags: mssql
+ :tickets:
+
+ fix to auto_identity_insert on db-url query
+
+ .. change::
+ :tags: mssql
+ :tickets:
+
+ added query_timeout to db-url query parms. currently works only for
+ pymssql
+
+ .. change::
+ :tags: mssql
+ :tickets:
+
+ tested with pymssql 0.8.0 (which is now LGPL)
+
+ .. change::
+ :tags: orm, bugs
+ :tickets: 441, 448, 439
+
+ 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,,.
+
+ .. change::
+ :tags: orm, bugs
+ :tickets:
+
+ 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).
+
+ .. change::
+ :tags: orm, bugs
+ :tickets: 454
+
+ extension() query option propagates to Mapper._instance() method so that
+ all loading-related methods get called
+
+ .. change::
+ :tags: orm, bugs
+ :tickets:
+
+ eager relation to an inheriting mapper wont fail if no rows returned for
+ the relationship.
+
+ .. change::
+ :tags: orm, bugs
+ :tickets: 486
+
+ eager relation loading bug fixed for eager relation on multiple
+ descendant classes
+
+ .. change::
+ :tags: orm, bugs
+ :tickets: 423
+
+ fix for very large topological sorts, courtesy ants.aasma at gmail
+
+ .. change::
+ :tags: orm, bugs
+ :tickets:
+
+ eager loading is slightly more strict about detecting "self-referential"
+ relationships, specifically between polymorphic mappers. this results in
+ an "eager degrade" to lazy loading.
+
+ .. change::
+ :tags: orm, bugs
+ :tickets: 449
+
+ improved support for complex queries embedded into "where" criterion for
+ query.select()
+
+ .. change::
+ :tags: orm, bugs
+ :tickets: 485
+
+ mapper options like eagerload(), lazyload(), deferred(), will work for
+ "synonym()" relationships
+
+ .. change::
+ :tags: orm, bugs
+ :tickets: 445
+
+ fixed bug where cascade operations incorrectly included deleted
+ collection items in the cascade
+
+ .. change::
+ :tags: orm, bugs
+ :tickets: 478
+
+ fixed relationship deletion error when one-to-many child item is moved
+ to a new parent in a single unit of work
+
+ .. change::
+ :tags: orm, bugs
+ :tickets:
+
+ 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
+
+ .. change::
+ :tags: orm, bugs
+ :tickets:
+
+ fix to deferred so that load operation doesnt mistakenly occur when only
+ PK col attributes are set
+
+ .. change::
+ :tags: orm, enhancements
+ :tickets: 385
+
+ implemented foreign_keys argument to mapper. use in
+ conjunction with primaryjoin/secondaryjoin arguments to specify/override
+ foreign keys defined on the Table instance.
+
+ .. change::
+ :tags: orm, enhancements
+ :tickets:
+
+ contains_eager('foo') automatically implies eagerload('foo')
+
+ .. change::
+ :tags: orm, enhancements
+ :tickets:
+
+ 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"
+
+ .. change::
+ :tags: orm, enhancements
+ :tickets:
+
+ added "contains_alias()" option for result set mapping to an alias of
+ the mapped table
+
+ .. change::
+ :tags: orm, enhancements
+ :tickets: 468
+
+ added support for py2.5 "with" statement with SessionTransaction
+
+ .. change::
+ :tags: extensions
+ :tickets:
+
+ added distinct() method to SelectResults. generally should only make a
+ difference when using count().
+
+ .. change::
+ :tags: extensions
+ :tickets: 472
+
+ added options() method to SelectResults, equivalent to query.options()
+
+ .. change::
+ :tags: extensions
+ :tickets: 462
+
+ added optional __table_opts__ dictionary to ActiveMapper, will send kw
+ options to Table objects
+
+ .. change::
+ :tags: extensions
+ :tickets: 467
+
+ added selectfirst(), selectfirst_by() to assign_mapper
+
+.. changelog::
+ :version: 0.3.4
+ :released: Tue Jan 23 2007
+
+ .. change::
+ :tags: general
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ added "fetchmany()" support to ResultProxy
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ added support for column "key" attribute to be useable in
+ row[<key>]/row.<key>
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ changed "BooleanExpression" to subclass from "BinaryExpression", so that
+ boolean expressions can also follow column-clause behaviors (i.e. label(),
+ etc).
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ trailing underscores are trimmed from func.<xxx> calls, such as func.if_()
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: sql
+ :tickets: 414
+
+ 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)
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ 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
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ trying to redefine a reflected primary key column as non-primary key raises
+ an error
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ 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)
+
+ .. change::
+ :tags: mssql
+ :tickets:
+
+ added an NVarchar type (produces NVARCHAR), also MSUnicode which provides
+ Unicode-translation for the NVarchar regardless of dialect convert_unicode
+ setting.
+
+ .. change::
+ :tags: postgres
+ :tickets: 424
+
+ fix to the initial checkfirst for tables to take current schema into
+ account
+
+ .. change::
+ :tags: postgres
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: postgres
+ :tickets:
+
+ added "BIGSERIAL" support for postgres table with
+ PGBigInteger/autoincrement
+
+ .. change::
+ :tags: postgres
+ :tickets: 402
+
+ fixes to postgres reflection to better handle when schema names are
+ present; thanks to jason (at) ncsmags.com
+
+ .. change::
+ :tags: mysql
+ :tickets: 420
+
+ 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
+
+ .. change::
+ :tags: mysql
+ :tickets: 418
+
+ 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
+
+ .. change::
+ :tags: firebird
+ :tickets: 408
+
+ order of constraint creation puts primary key first before all other
+ constraints; required for firebird, not a bad idea for others
+
+ .. change::
+ :tags: firebird
+ :tickets: 409
+
+ Firebird fix to autoload multifield foreign keys
+
+ .. change::
+ :tags: firebird
+ :tickets: 409
+
+ Firebird NUMERIC type properly handles a type without precision
+
+ .. change::
+ :tags: oracle
+ :tickets:
+
+ *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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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".
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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"
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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).
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ fix to "proxy=True" behavior on synonym()
+
+ .. change::
+ :tags: orm
+ :tickets: 427
+
+ fixed bug where delete-orphan basically didn't work with many-to-many
+ relationships, backref presence generally hid the symptom
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ basic idea of "session.merge()" actually implemented. needs more testing.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ added "compile_mappers()" function as a shortcut to compiling all mappers
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ fix to MapperExtension create_instance so that entity_name properly
+ associated with new instance
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ speed enhancements to ORM object instantiation, eager loading of rows
+
+ .. change::
+ :tags: orm
+ :tickets: 406
+
+ invalid options sent to 'cascade' string will raise an exception
+
+ .. change::
+ :tags: orm
+ :tickets: 407
+
+ fixed bug in mapper refresh/expire whereby eager loaders didnt properly
+ re-populate item lists
+
+ .. change::
+ :tags: orm
+ :tickets: 413
+
+ fix to post_update to ensure rows are updated even for non insert/delete
+ scenarios
+
+ .. change::
+ :tags: orm
+ :tickets: 412
+
+ added an error message if you actually try to modify primary key values on
+ an entity and then flush it
+
+ .. change::
+ :tags: extensions
+ :tickets: 426
+
+ added "validate=False" argument to assign_mapper, if True will ensure that
+ only mapped attributes are named
+
+ .. change::
+ :tags: extensions
+ :tickets:
+
+ assign_mapper gets "options", "instances" functions added (i.e.
+ MyClass.instances())
+
+.. changelog::
+ :version: 0.3.3
+ :released: Fri Dec 15 2006
+
+ .. change::
+ :tags:
+ :tickets:
+
+ string-based FROM clauses fixed, i.e. select(..., from_obj=["sometext"])
+
+ .. change::
+ :tags:
+ :tickets:
+
+ fixes to passive_deletes flag, lazy=None (noload) flag
+
+ .. change::
+ :tags:
+ :tickets:
+
+ added example/docs for dealing with large collections
+
+ .. change::
+ :tags:
+ :tickets:
+
+ added object_session() method to sqlalchemy namespace
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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
+
+ .. change::
+ :tags:
+ :tickets: 396
+
+ patch that makes MySQL rowcount work correctly!
+
+ .. change::
+ :tags:
+ :tickets:
+
+ fix to MySQL catch of 2006/2014 errors to properly re-raise OperationalError
+ exception
+
+.. changelog::
+ :version: 0.3.2
+ :released: Sun Dec 10 2006
+
+ .. change::
+ :tags:
+ :tickets: 387
+
+ major connection pool bug fixed. fixes MySQL out of sync
+ errors, will also prevent transactions getting rolled back
+ accidentally in all DBs
+
+ .. change::
+ :tags:
+ :tickets:
+
+ major speed enhancements vs. 0.3.1, to bring speed
+ back to 0.2.8 levels
+
+ .. change::
+ :tags:
+ :tickets:
+
+ made conditional dozens of debug log calls that were
+ time-intensive to generate log messages
+
+ .. change::
+ :tags:
+ :tickets:
+
+ fixed bug in cascade rules whereby the entire object graph
+ could be unnecessarily cascaded on the save/update cascade
+
+ .. change::
+ :tags:
+ :tickets:
+
+ various speedups in attributes module
+
+ .. change::
+ :tags:
+ :tickets: 388
+
+ 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
+
+ .. change::
+ :tags:
+ :tickets:
+
+ MySQL detects errors 2006 (server has gone away) and 2014
+ (commands out of sync) and invalidates the connection on which it occured.
+
+ .. change::
+ :tags:
+ :tickets: 307
+
+ MySQL bool type fix:
+
+ .. change::
+ :tags:
+ :tickets: 382, 349
+
+ postgres reflection fixes:
+
+ .. change::
+ :tags:
+ :tickets: 247
+
+ added keywords for EXCEPT, INTERSECT, EXCEPT ALL, INTERSECT ALL
+
+ .. change::
+ :tags:
+ :tickets: 2110
+
+ assign_mapper in assignmapper extension returns the created mapper
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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"
+
+ .. change::
+ :tags:
+ :tickets:
+
+ added onupdate and ondelete keyword arguments to ForeignKey; propagate
+ to underlying ForeignKeyConstraint if present. (dont propagate in the
+ other direction, however)
+
+ .. change::
+ :tags:
+ :tickets:
+
+ fix to session.update() to preserve "dirty" status of incoming object
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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)
+
+ .. change::
+ :tags:
+ :tickets:
+
+ improved support for disabling save-update cascade via cascade="none" etc.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+.. changelog::
+ :version: 0.3.1
+ :released: Mon Nov 13 2006
+
+ .. change::
+ :tags: engine/pool
+ :tickets:
+
+ some new Pool utility classes, updated docs
+
+ .. change::
+ :tags: engine/pool
+ :tickets:
+
+ "use_threadlocal" on Pool defaults to False (same as create_engine)
+
+ .. change::
+ :tags: engine/pool
+ :tickets:
+
+ fixed direct execution of Compiled objects
+
+ .. change::
+ :tags: engine/pool
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: databases/types
+ :tickets:
+
+ MySQL catches exception on "describe" and reports as NoSuchTableError
+
+ .. change::
+ :tags: databases/types
+ :tickets:
+
+ further fixes to sqlite booleans, weren't working as defaults
+
+ .. change::
+ :tags: databases/types
+ :tickets:
+
+ fix to postgres sequence quoting when using schemas
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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().
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ adjustments to reworked eager query generation to not fail on circular
+ eager-loaded relationships (like backrefs)
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ fixed bug where eagerload() (nor lazyload()) option didn't properly
+ instruct the Query whether or not to use "nesting" when producing a
+ LIMIT query.
+
+ .. change::
+ :tags: orm
+ :tickets: 360
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets: 325
+
+ implemented from_obj argument for query.count, improves count function
+ on selectresults
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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)
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ new extension sqlalchemy.ext.associationproxy, provides transparent
+ "association object" mappings. new example
+ examples/association/proxied_association.py illustrates.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ improvement to single table inheritance to load full hierarchies beneath
+ the target class
+
+ .. change::
+ :tags: orm
+ :tickets: 362
+
+ fix to subtle condition in topological sort where a node could appear twice,
+ for
+
+ .. change::
+ :tags: orm
+ :tickets: 365
+
+ additional rework to topological sort, refactoring, for
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ "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
+
+.. changelog::
+ :version: 0.3.0
+ :released: Sun Oct 22 2006
+
+ .. change::
+ :tags: general
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: general
+ :tickets:
+
+ the documentation-generation system has been overhauled to be
+ much simpler in design and more integrated with Markdown
+
+ .. change::
+ :tags: sqlite
+ :tickets:
+
+ sqlite boolean datatype converts False/True to 0/1 by default
+
+ .. change::
+ :tags: sqlite
+ :tickets: 335
+
+ fixes to Date/Time (SLDate/SLTime) types; works as good as postgres
+ now
+
+ .. change::
+ :tags: ms-sql
+ :tickets:
+
+ fixes bug 261 (table reflection broken for MS-SQL case-sensitive
+ databases)
+
+ .. change::
+ :tags: ms-sql
+ :tickets:
+
+ can now specify port for pymssql
+
+ .. change::
+ :tags: ms-sql
+ :tickets:
+
+ introduces new "auto_identity_insert" option for auto-switching
+ between "SET IDENTITY_INSERT" mode when values specified for IDENTITY columns
+
+ .. change::
+ :tags: ms-sql
+ :tickets:
+
+ now supports multi-column foreign keys
+
+ .. change::
+ :tags: ms-sql
+ :tickets:
+
+ fix to reflecting date/datetime columns
+
+ .. change::
+ :tags: ms-sql
+ :tickets:
+
+ NCHAR and NVARCHAR type support added
+
+ .. change::
+ :tags: oracle
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: firebird
+ :tickets:
+
+ aliases do not use "AS"
+
+ .. change::
+ :tags: firebird
+ :tickets:
+
+ correctly raises NoSuchTableError when reflecting non-existent table
+
+ .. change::
+ :tags: schema
+ :tickets:
+
+ 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
+
+ .. change::
+ :tags: schema
+ :tickets:
+
+ 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
+
+ .. change::
+ :tags: schema
+ :tickets:
+
+ ForeignKey(Constraint) supports "use_alter=True", to create/drop a foreign key
+ via ALTER. this allows circular foreign key relationships to be set up.
+
+ .. change::
+ :tags: schema
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: schema
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: schema
+ :tickets:
+
+ added UniqueConstraint (goes at Table level), CheckConstraint
+ (goes at Table or Column level).
+
+ .. change::
+ :tags: schema
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: schema
+ :tickets:
+
+ added autoincrement=True to Column; will disable schema generation
+ of SERIAL/AUTO_INCREMENT/identity seq for postgres/mysql/mssql if
+ explicitly set to False
+
+ .. change::
+ :tags: schema
+ :tickets:
+
+ TypeEngine objects now have methods to deal with copying and comparing
+ values of their specific type. Currently used by the ORM, see below.
+
+ .. change::
+ :tags: schema
+ :tickets:
+
+ 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
+
+ .. change::
+ :tags: schema
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: connections/pooling/execution
+ :tickets:
+
+ 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
+
+ .. change::
+ :tags: connections/pooling/execution
+ :tickets:
+
+ fixed bug where Connection wouldnt lose its Transaction
+ after commit/rollback
+
+ .. change::
+ :tags: connections/pooling/execution
+ :tickets:
+
+ added scalar() method to ComposedSQLEngine, ResultProxy
+
+ .. change::
+ :tags: connections/pooling/execution
+ :tickets:
+
+ 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).
+
+ .. change::
+ :tags: connections/pooling/execution
+ :tickets:
+
+ ResultProxy.fetchall() internally uses DBAPI fetchall() for better efficiency,
+ added to mapper iteration as well (courtesy Michael Twomey)
+
+ .. change::
+ :tags: construction, sql
+ :tickets: 292
+
+ changed "for_update" parameter to accept False/True/"nowait"
+ and "read", the latter two of which are interpreted only by
+ Oracle and Mysql
+
+ .. change::
+ :tags: construction, sql
+ :tickets:
+
+ added extract() function to sql dialect
+ (SELECT extract(field FROM expr))
+
+ .. change::
+ :tags: construction, sql
+ :tickets:
+
+ BooleanExpression includes new "negate" argument to specify
+ the appropriate negation operator if one is available.
+
+ .. change::
+ :tags: construction, sql
+ :tickets:
+
+ calling a negation on an "IN" or "IS" clause will result in
+ "NOT IN", "IS NOT" (as opposed to NOT (x IN y)).
+
+ .. change::
+ :tags: construction, sql
+ :tickets: 172
+
+ 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
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ instances() method moved to Query now, backwards-compatible
+ version remains on Mapper.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ more rearrangements of unit-of-work commit scheme to better allow
+ dependencies within circular flushes to work properly...updated
+ task traversal/logging implementation
+
+ .. change::
+ :tags: orm
+ :tickets: 321
+
+ polymorphic mappers (i.e. using inheritance) now produces INSERT
+ statements in order of tables across all inherited classes
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ "association" mappings simplified to take advantage of
+ automatic "row switch" feature
+
+ .. change::
+ :tags: orm
+ :tickets: 212
+
+ "custom list classes" is now implemented via the "collection_class"
+ keyword argument to relation(). the old way still works but is
+ deprecated
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ added "viewonly" flag to relation(), allows construction of
+ relations that have no effect on the flush() process.
+
+ .. change::
+ :tags: orm
+ :tickets: 292
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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
+
+ .. change::
+ :tags: orm
+ :tickets: 208
+
+ post_update behavior improved; does a better job at not
+ updating too many rows, updates only required columns
+
+ .. change::
+ :tags: orm
+ :tickets: 308
+
+ 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
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ fix to deferred group loading
+
+ .. change::
+ :tags: orm
+ :tickets: 346
+
+ session.flush() wont close a connection it opened
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ added "column_prefix=None" argument to mapper; prepends the
+ given string (typically '_') to column-based attributes automatically
+ set up from the mapper's Table
+
+ .. change::
+ :tags: orm
+ :tickets: 315
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ removed "is_primary" flag from mapper.
--- /dev/null
+
+==============
+0.4 Changelog
+==============
+
+
+.. changelog::
+ :version: 0.4.8
+ :released: Sun Oct 12 2008
+
+ .. change::
+ :tags: orm
+ :tickets: 1039
+
+ Fixed bug regarding inherit_condition passed
+ with "A=B" versus "B=A" leading to errors
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Changes made to new, dirty and deleted
+ collections in
+ SessionExtension.before_flush() will take
+ effect for that flush.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Added label() method to InstrumentedAttribute
+ to establish forwards compatibility with 0.5.
+
+ .. change::
+ :tags: sql
+ :tickets: 1074
+
+ column.in_(someselect) can now be used as
+ a columns-clause expression without the subquery
+ bleeding into the FROM clause
+
+ .. change::
+ :tags: mysql
+ :tickets: 1146
+
+ Added MSMediumInteger type.
+
+ .. change::
+ :tags: sqlite
+ :tickets: 968
+
+ Supplied a custom strftime() function which
+ handles dates before 1900.
+
+ .. change::
+ :tags: sqlite
+ :tickets:
+
+ String's (and Unicode's, UnicodeText's, etc.)
+ convert_unicode logic disabled in the sqlite dialect,
+ to adjust for pysqlite 2.5.0's new requirement that
+ only Python unicode objects are accepted;
+ http://itsystementwicklung.de/pipermail/list-pysqlite/2008-March/000018.html
+
+ .. change::
+ :tags: oracle
+ :tickets: 1155
+
+ has_sequence() now takes schema name into account
+
+ .. change::
+ :tags: oracle
+ :tickets: 1121
+
+ added BFILE to the list of reflected types
+
+.. changelog::
+ :version: 0.4.7p1
+ :released: Thu Jul 31 2008
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Added "add()" and "add_all()" to scoped_session
+ methods. Workaround for 0.4.7:
+
+ from sqlalchemy.orm.scoping import ScopedSession,\
+ instrument
+ setattr(
+ ScopedSession, "add", instrument("add"))
+ setattr(
+ ScopedSession, "add_all", instrument("add_all"))
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Fixed non-2.3 compatible usage of set() and generator
+ expression within relation().
+
+.. changelog::
+ :version: 0.4.7
+ :released: Sat Jul 26 2008
+
+ .. change::
+ :tags: orm
+ :tickets: 1058
+
+ 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
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ fixed bug preventing merge() from functioning in
+ conjunction with a comparable_property()
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets: 976
+
+ Added is_active flag to Sessions to detect when
+ a transaction is in progress. This
+ flag is always True with a "transactional"
+ (in 0.5 a non-"autocommit") Session.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Fixed bug when calling select([literal('foo')])
+ or select([bindparam('foo')]).
+
+ .. change::
+ :tags: schema
+ :tickets: 571
+
+ 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.
+
+ .. change::
+ :tags: schema
+ :tickets: 571, 820
+
+ 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.
+
+ .. change::
+ :tags: postgres
+ :tickets:
+
+ Repaired server_side_cursors to properly detect
+ text() clauses.
+
+ .. change::
+ :tags: postgres
+ :tickets: 1092
+
+ Added PGCidr type.
+
+ .. change::
+ :tags: mysql
+ :tickets:
+
+ Added 'CALL' to the list of SQL keywords which return
+ result rows.
+
+ .. change::
+ :tags: oracle
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: oracle
+ :tickets: 709
+
+ 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
+
+ .. change::
+ :tags: oracle
+ :tickets: 1062
+
+ 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).
+
+ .. change::
+ :tags: oracle
+ :tickets:
+
+ 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.
+
+.. changelog::
+ :version: 0.4.6
+ :released: Sat May 10 2008
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Also re-established viewonly relation() configurations
+ that join across multiple tables.
+
+ .. change::
+ :tags: orm
+ :tickets: 610
+
+ 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)
+
+ .. change::
+ :tags: orm
+ :tickets: 1036
+
+ repaired single table inheritance such that you
+ can single-table inherit from a joined-table inherting
+ mapper without issue.
+
+ .. change::
+ :tags: orm
+ :tickets: 1027
+
+ Fixed "concatenate tuple" bug which could occur with
+ Query.order_by() if clause adaption had taken place.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Also re-established viewonly relation() configurations that
+ join across multiple tables.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets: 1015
+
+ refined mapper._save_obj() which was unnecessarily calling
+ __ne__() on scalar values during flush
+
+ .. change::
+ :tags: orm
+ :tickets: 1019
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ added an example dynamic_dict/dynamic_dict.py, illustrating
+ a simple way to place dictionary behavior on top of
+ a dynamic_loader.
+
+ .. change::
+ :tags: declarative, extension
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: declarative, extension
+ :tickets:
+
+ fixed reentrant mapper compile hang when
+ a declared attribute is used within ForeignKey,
+ ie. ForeignKey(MyOtherClass.someattribute)
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Added COLLATE support via the .collate(<collation>)
+ expression operator and collate(<expr>, <collation>) sql
+ function.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Fixed bug with union() when applied to non-Table connected
+ select statements
+
+ .. change::
+ :tags: sql
+ :tickets: 1014
+
+ improved behavior of text() expressions when used as
+ FROM clauses, such as select().select_from(text("sometext"))
+
+ .. change::
+ :tags: sql
+ :tickets: 1021
+
+ Column.copy() respects the value of "autoincrement",
+ fixes usage with Migrate
+
+ .. change::
+ :tags: engines
+ :tickets:
+
+ Pool listeners can now be provided as a dictionary of
+ callables or a (possibly partial) duck-type of
+ PoolListener, your choice.
+
+ .. change::
+ :tags: engines
+ :tickets:
+
+ 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).
+
+ .. change::
+ :tags: ext
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: mssql
+ :tickets: 1005
+
+ 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
+
+ .. change::
+ :tags: mssql
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: firebird
+ :tickets:
+
+ Handle the "SUBSTRING(:string FROM :start FOR :length)"
+ builtin.
+
+.. changelog::
+ :version: 0.4.5
+ :released: Fri Apr 04 2008
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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).
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Also fixed behavior in merge() whereby collection elements
+ present on the destination but not the merged collection
+ were not being removed from the destination.
+
+ .. change::
+ :tags: orm
+ :tickets: 995
+
+ Added a more aggressive check for "uncompiled mappers",
+ helps particularly with declarative layer
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Added comparable_property(), adds query Comparator
+ behavior to regular, unmanaged Python properties
+
+ .. change::
+ :tags: orm, Company.employees.of_type(Engineer), 'machines'
+ :tickets:
+
+ 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(
+
+ ))
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ query.order_by() and query.group_by() will accept
+ multiple arguments using *args (like select()
+ already does).
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Added some convenience descriptors to Query:
+ query.statement returns the full SELECT construct,
+ query.whereclause returns just the WHERE part of the
+ SELECT construct.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Fixed/covered case when using a False/0 value as a
+ polymorphic discriminator.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Fixed bug which was preventing synonym() attributes from
+ being used with inheritance
+
+ .. change::
+ :tags: orm
+ :tickets: 996
+
+ Fixed SQL function truncation of trailing underscores
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Session.execute can now find binds from metadata
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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).
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets: 895
+
+ 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
+
+ - 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Fixed order_by calculation in Query to properly alias
+ mapper-config'ed order_by when using select_from()
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Refactored the diffing logic that kicks in when replacing
+ one collection with another into collections.bulk_replace,
+ useful to anyone building multi-level collections.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Cascade traversal algorithm converted from recursive to
+ iterative to support deep object graphs.
+
+ .. change::
+ :tags: sql
+ :tickets: 999
+
+ 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
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ '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.
+
+ .. change::
+ :tags: sql
+ :tickets: 791, 993
+
+ 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>'".
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ random() is now a generic sql function and will compile to
+ the database's random implementation, if any.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ update().values() and insert().values() take keyword
+ arguments.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ 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().
+
+ .. change::
+ :tags: oracle
+ :tickets:
+
+ 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".
+
+ .. change::
+ :tags: oracle
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: declarative, extension
+ :tickets:
+
+ 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))
+
+ .. change::
+ :tags: declarative, extension
+ :tickets:
+
+ The "deferred" function is usable with "declarative".
+ Simplest usage is to declare deferred and Column together,
+ e.g.: data = deferred(Column(Text))
+
+ .. change::
+ :tags: declarative, extension
+ :tickets:
+
+ Declarative also gained @synonym_for(...) and
+ @comparable_using(...), front-ends for synonym and
+ comparable_property.
+
+ .. change::
+ :tags: declarative, extension
+ :tickets: 995
+
+ Improvements to mapper compilation when using declarative;
+ already-compiled mappers will still trigger compiles of
+ other uncompiled mappers when used
+
+ .. change::
+ :tags: declarative, extension
+ :tickets:
+
+ Declarative will complete setup for Columns lacking names,
+ allows a more DRY syntax.
+
+ class Foo(Base):
+ __tablename__ = 'foos'
+ id = Column(Integer, primary_key=True)
+
+ .. change::
+ :tags: declarative, extension
+ :tickets:
+
+ inheritance in declarative can be disabled when sending
+ "inherits=None" to __mapper_args__.
+
+ .. change::
+ :tags: declarative, extension
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: postgres
+ :tickets: 1001
+
+ 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
+
+ .. change::
+ :tags: oracle
+ :tickets:
+
+ 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".
+
+ .. change::
+ :tags: oracle
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: mssql
+ :tickets: 979
+
+ Reflected tables will now automatically load other tables
+ which are referenced by Foreign keys in the auto-loaded
+ table,.
+
+ .. change::
+ :tags: mssql
+ :tickets: 916
+
+ Added executemany check to skip identity fetch,.
+
+ .. change::
+ :tags: mssql
+ :tickets: 884
+
+ Added stubs for small date type.
+
+ .. change::
+ :tags: mssql
+ :tickets:
+
+ Added a new 'driver' keyword parameter for the pyodbc dialect.
+ Will substitute into the ODBC connection string if given,
+ defaults to 'SQL Server'.
+
+ .. change::
+ :tags: mssql
+ :tickets:
+
+ Added a new 'max_identifier_length' keyword parameter for
+ the pyodbc dialect.
+
+ .. change::
+ :tags: mssql
+ :tickets:
+
+ Improvements to pyodbc + Unix. If you couldn't get that
+ combination to work before, please try again.
+
+ .. change::
+ :tags: mysql
+ :tickets:
+
+ The connection.info keys the dialect uses to cache server
+ settings have changed and are now namespaced.
+
+.. changelog::
+ :version: 0.4.4
+ :released: Wed Mar 12 2008
+
+ .. change::
+ :tags: sql
+ :tickets: 975
+
+ Can again create aliases of selects against textual FROM
+ clauses.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ The value of a bindparam() can be a callable, in which
+ case it's evaluated at statement execution time to get the
+ value.
+
+ .. change::
+ :tags: sql
+ :tickets: 978
+
+ 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)
+
+ .. change::
+ :tags: sql
+ :tickets: 936
+
+ Implemented two-phase API for "threadlocal" engine, via
+ engine.begin_twophase(), engine.prepare()
+
+ .. change::
+ :tags: sql
+ :tickets: 986
+
+ Fixed bug which was preventing UNIONS from being
+ cloneable.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Added "bind" keyword argument to insert(), update(),
+ delete() and DDL(). The .bind property is now assignable
+ on those statements as well as on select().
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Insert statements can now be compiled with extra "prefix"
+ words between INSERT and INTO, for vendor extensions like
+ MySQL's INSERT IGNORE INTO table.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets: 985
+
+ Repaired behavior of == and != operators at the relation()
+ level when compared against NULL for one-to-one relations
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Fixed bug whereby session.expire() attributes were not
+ loading on an polymorphically-mapped instance mapped by a
+ select_table mapper.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ session.refresh() and session.expire() raise an error when
+ called on instances which are not persistent within the
+ session
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Fixed potential generative bug when the same Query was
+ used to generate multiple Query objects using join().
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Deprecated Query methods apply_sum(), apply_max(),
+ apply_min(), apply_avg(). Better methodologies are
+ coming....
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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')
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Preventive code against a potential lost-reference bug in
+ flush().
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Synonyms riding on top of existing descriptors are now
+ full proxies to those descriptors.
+
+ .. change::
+ :tags: dialects
+ :tickets:
+
+ Invalid SQLite connection URLs now raise an error.
+
+ .. change::
+ :tags: dialects
+ :tickets: 981
+
+ postgres TIMESTAMP renders correctly
+
+ .. change::
+ :tags: dialects
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: extensions
+ :tickets:
+
+ 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.
+
+.. changelog::
+ :version: 0.4.3
+ :released: Thu Feb 14 2008
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Added a callable-based DDL events interface, adds hooks
+ before and after Tables and MetaData create and drop.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ 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().
+
+ .. change::
+ :tags: sql
+ :tickets: 727
+
+ Added "ilike()" operator to column operations. Compiles to
+ ILIKE on postgres, lower(x) LIKE lower(y) on all
+ others.
+
+ .. change::
+ :tags: sql
+ :tickets: 943
+
+ Added "now()" as a generic function; on SQLite, Oracle
+ and MSSQL compiles as "CURRENT_TIMESTAMP"; "now()" on
+ all others.
+
+ .. change::
+ :tags: sql
+ :tickets: 962
+
+ 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
+
+ .. change::
+ :tags: sql
+ :tickets: 962
+
+ cast() accepts text('something') and other non-literal
+ operands properly
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ fixed bug in result proxy where anonymously generated
+ column labels would not be accessible using their straight
+ string name
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Deferrable constraints can now be defined.
+
+ .. change::
+ :tags: sql
+ :tickets: 915
+
+ 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.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ The anonymous 'label' generated for otherwise unlabeled
+ functions and expressions now propagates outwards at compile
+ time for expressions like select([select([func.foo()])]).
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ 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.)
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets: 961
+
+ Fixed merge() collection-doubling bug when merging transient
+ entities with backref'ed collections.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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()
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ The proper error message is raised when trying to access
+ expired instance attributes with no session present
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ dynamic_loader() / lazy="dynamic" now accepts and uses
+ the order_by parameter in the same way in which it works
+ with relation().
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Added expire_all() method to Session. Calls expire() for
+ all persistent instances. This is handy in conjunction
+ with...
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets: 938
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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])
+
+ .. change::
+ :tags: orm, ('employees', people.join(engineer)), Engineer.name
+ :tickets:
+
+ 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(
+
+ )
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ General improvements to the behavior of join() in
+ conjunction with polymorphic mappers, i.e. joining from/to
+ polymorphic mappers and properly applying aliases.
+
+ .. change::
+ :tags: orm
+ :tickets: 933
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets: 946
+
+ 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".
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Fixed bug in polymorphic inheritance which made it difficult
+ to set a working "order_by" on a polymorphic mapper.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Fixed a rather expensive call in Query that was slowing down
+ polymorphic queries.
+
+ .. change::
+ :tags: orm
+ :tickets: 954
+
+ "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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets: 964, 940
+
+ Miscellaneous tickets:
+
+ .. change::
+ :tags: general
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: general
+ :tickets:
+
+ Warnings are now issued as type exceptions.SAWarning.
+
+ .. change::
+ :tags: dialects
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: dialects
+ :tickets:
+
+ table_names on SQLite now picks up temporary tables as well.
+
+ .. change::
+ :tags: dialects
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: dialects
+ :tickets:
+
+ Fixed reflection of TIME columns on SQLite.
+
+ .. change::
+ :tags: dialects
+ :tickets: 580
+
+ Finally added PGMacAddr type to postgres
+
+ .. change::
+ :tags: dialects
+ :tickets:
+
+ Reflect the sequence associated to a PK field (typically
+ with a BEFORE INSERT trigger) under Firebird
+
+ .. change::
+ :tags: dialects
+ :tickets: 941
+
+ 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
+
+ .. change::
+ :tags: dialects
+ :tickets:
+
+ MSSQL now includes EXEC in the _is_select regexp, which
+ should allow row-returning stored procedures to be used.
+
+ .. change::
+ :tags: dialects
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: ext
+ :tickets:
+
+ Changed ext.activemapper to use a non-transactional session
+ for the objectstore.
+
+ .. change::
+ :tags: ext
+ :tickets:
+
+ Fixed output order of "['a'] + obj.proxied" binary operation
+ on association-proxied lists.
+
+.. changelog::
+ :version: 0.4.2p3
+ :released: Wed Jan 09 2008
+
+ .. change::
+ :tags: general
+ :tickets:
+
+ sub version numbering scheme changed to suite
+ setuptools version number rules; easy_install -u
+ should now get this version over 0.4.2.
+
+ .. change::
+ :tags: sql
+ :tickets: 912
+
+ 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
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ new UnicodeText type is added, to specify an
+ encoded, unlengthed Text type
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ fixed bug in union() so that select() statements
+ which don't derive from FromClause objects can be
+ unioned
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ fixed bug with session.dirty when using "mutable
+ scalars" (such as PickleTypes)
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ added a more descriptive error message when flushing
+ on a relation() that has non-locally-mapped columns
+ in its primary or secondary join condition
+
+ .. change::
+ :tags: dialects
+ :tickets:
+
+ Fixed reflection of mysql empty string column
+ defaults.
+
+ .. change::
+ :tags: sql
+ :tickets: 912
+
+ 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)
+
+ .. change::
+ :tags: sql
+ :tickets: 924
+
+ generative select.order_by(None) / group_by(None)
+ was not managing to reset order by/group by
+ criterion, fixed
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ suppressing *all* errors in
+ InstanceState.__cleanup() now.
+
+ .. change::
+ :tags: orm
+ :tickets: 922
+
+ fixed an attribute history bug whereby assigning a
+ new collection to a collection-based attribute which
+ already had pending changes would generate incorrect
+ history
+
+ .. change::
+ :tags: orm
+ :tickets: 925
+
+ fixed delete-orphan cascade bug whereby setting the
+ same object twice to a scalar attribute could log it
+ as an orphan
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Fixed cascades on a += assignment to a list-based
+ relation.
+
+ .. change::
+ :tags: orm
+ :tickets: 919
+
+ 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)
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ fixed bug which could occur with polymorphic "union"
+ mapper which falls back to "deferred" loading of
+ inheriting tables
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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).
+
+ .. change::
+ :tags: ext
+ :tickets:
+
+ '+', '*', '+=' and '*=' support for association
+ proxied lists.
+
+ .. change::
+ :tags: dialects
+ :tickets: 923
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets: 920
+
+ Fixed in-place set mutation operators for set collections and association
+ proxied sets.
+
+ .. change::
+ :tags: dialects
+ :tickets: 913
+
+ Fixed the missing call to subtype result processor for the PGArray
+ type.
+
+.. changelog::
+ :version: 0.4.2
+ :released: Wed Jan 02 2008
+
+ .. change::
+ :tags: sql
+ :tickets: 615
+
+ 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
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ 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().
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ select().as_scalar() will raise an exception if the select does not have
+ exactly one expression in its columns clause.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ bindparam() objects themselves can be used as keys for execute(), i.e.
+ statement.execute({bind1:'foo', bind2:'bar'})
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ selectables (and others) will issue a warning when two columns in
+ their exported columns collection conflict based on name.
+
+ .. change::
+ :tags: sql
+ :tickets: 890
+
+ tables with schemas can still be used in sqlite, firebird,
+ schema name just gets dropped
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ 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"
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ column labels in the form "tablename.columname", i.e. with a dot, are now
+ supported.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ from_obj keyword argument to select() can be a scalar or a list.
+
+ .. change::
+ :tags: orm
+ :tickets: 871
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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".
+
+ .. change::
+ :tags: orm
+ :tickets: 490
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets: 907
+
+ 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()
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ columns which are missing from a Query's select statement
+ now get automatically deferred during load.
+
+ .. change::
+ :tags: orm
+ :tickets: 908
+
+ 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
+
+ .. change::
+ :tags: orm
+ :tickets: 899
+
+ fixed Query bug when filter_by() compares a relation against None
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ improved support for pickling of mapped entities. Per-instance
+ lazy/deferred/expired callables are now serializable so that
+ they serialize and deserialize with _state.
+
+ .. change::
+ :tags: orm
+ :tickets: 801
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: attrname, orm
+ :tickets:
+
+ 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,).
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ query.order_by() takes into account aliased joins, i.e.
+ query.join('orders', aliased=True).order_by(Order.id)
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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().
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ eagerloading will work with mappers added via add_entity().
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ also with dynamic, implemented correct count() behavior as well
+ as other helper methods.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets: 893
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets: 883
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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().
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ fixed backref bug where you could not del instance.attr if attr
+ was None
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Assigning an incompatible collection type to a relation attribute now
+ raises TypeError instead of sqlalchemy's ArgumentError.
+
+ .. change::
+ :tags: orm
+ :tickets: 886
+
+ 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.
+
+ .. change::
+ :tags: orm, newval1, newval2
+ :tickets:
+
+ Custom collections can now specify a @converter method to translate
+ objects used in "bulk" assignment into a stream of values, as in::
+
+ obj.col =
+ # 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.
+
+ .. change::
+ :tags: orm
+ :tickets: 872
+
+ fixed endless loop issue when using lazy="dynamic" on both
+ sides of a bi-directional relationship
+
+ .. change::
+ :tags: orm
+ :tickets: 904
+
+ more fixes to the LIMIT/OFFSET aliasing applied with Query + eagerloads,
+ in this case when mapped against a select statement
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ fixed bug which could arise when using session.begin_nested() in conjunction
+ with more than one level deep of enclosing session.begin() statements
+
+ .. change::
+ :tags: orm
+ :tickets: 914
+
+ fixed session.refresh() with instance that has custom entity_name
+
+ .. change::
+ :tags: dialects
+ :tickets:
+
+ sqlite SLDate type will not erroneously render "microseconds" portion
+ of a datetime or time object.
+
+ .. change::
+ :tags: dialects
+ :tickets: 902
+
+ 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
+
+ .. change::
+ :tags: dialects
+ :tickets: 824, 839, 842, 901
+
+ MSSQL
+ - PyODBC no longer has a global "set nocount on".
+ - Fix non-identity integer PKs on autload
+ - Better support for convert_unicode
+ - Less strict date conversion for pyodbc/adodbapi
+ - Schema-qualified tables / autoload
+
+ .. change::
+ :tags: firebird, backend
+ :tickets: 410
+
+ does properly reflect domains (partially fixing) and
+ PassiveDefaults
+
+ .. change::
+ :tags: 3562, firebird, backend
+ :tickets:
+
+ reverted to use default poolclass (was set to SingletonThreadPool in
+ 0.4.0 for test purposes)
+
+ .. change::
+ :tags: firebird, backend
+ :tickets:
+
+ map func.length() to 'char_length' (easily overridable with the UDF
+ 'strlen' on old versions of Firebird)
+
+.. changelog::
+ :version: 0.4.1
+ :released: Sun Nov 18 2007
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ the "shortname" keyword parameter on bindparam() has been
+ deprecated.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Added contains operator (generates a "LIKE %<other>%" clause).
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ 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).
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: sql
+ :tickets: 819
+
+ 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
+
+ .. change::
+ :tags: sql
+ :tickets: 833
+
+ Removed regular expression step from most statement compilations.
+ Also fixes
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Fixed empty (zero column) sqlite inserts, allowing inserts on
+ autoincrementing single column tables.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Fixed expression translation of text() clauses; this repairs various
+ ORM scenarios where literal text is used for SQL expressions
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Removed ClauseParameters object; compiled.params returns a regular
+ dictionary now, as well as result.last_inserted_params() /
+ last_updated_params().
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ 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
+
+ .. change::
+ :tags: sql
+ :tickets: 844
+
+ func. objects can be pickled/unpickled
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: sql
+ :tickets: 573
+
+ Added a field ("info") for storing arbitrary data on schema items
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ fixed the close() method on Transaction when using strategy='threadlocal'
+
+ .. change::
+ :tags: sql
+ :tickets: 853
+
+ fix to compiled bind parameters to not mistakenly populate None
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ <Engine|Connection>._execute_clauseelement becomes a public method
+ Connectable.execute_clauseelement
+
+ .. change::
+ :tags: orm
+ :tickets: 843
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets: 802
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets: 767
+
+ added op() operator to instrumented attributes; i.e.
+ User.name.op('ilike')('%somename%')
+
+ .. change::
+ :tags: orm
+ :tickets: 676
+
+ 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 '==')
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ the "properties" accessor on Mapper is removed; it now throws an informative
+ exception explaining the usage of mapper.get_property() and
+ mapper.iterate_properties
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ added having() method to Query, applies HAVING to the generated statement
+ in the same way as filter() appends to the WHERE clause.
+
+ .. change::
+ :tags: orm
+ :tickets: 777
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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).
+
+ .. change::
+ :tags: orm
+ :tickets: 848
+
+ query doesn't throw an error if you use distinct() and an order_by()
+ containing UnaryExpressions (or other) together
+
+ .. change::
+ :tags: orm
+ :tickets: 786
+
+ order_by() expressions from joined tables are properly added to columns
+ clause when using distinct()
+
+ .. change::
+ :tags: orm
+ :tickets: 858
+
+ 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)
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ added a little more checking for garbage-collection dereferences in
+ InstanceState.__cleanup() to reduce "gc ignored" errors on app
+ shutdown
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ The session API has been solidified:
+
+ .. change::
+ :tags: orm
+ :tickets: 840
+
+ It's an error to session.save() an object which is already
+ persistent
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ It's an error to session.delete() an object which is *not*
+ persistent.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ session.update() and session.delete() raise an error when updating
+ or deleting an instance that is already in the session with a
+ different identity.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets: 834
+
+ Fixed a truncation error when re-assigning a subset of a collection
+ (obj.relation = obj.relation[1:])
+
+ .. change::
+ :tags: orm
+ :tickets: 832
+
+ De-cruftified backref configuration code, backrefs which step on
+ existing properties now raise an error
+
+ .. change::
+ :tags: orm
+ :tickets: 831
+
+ Improved behavior of add_property() etc., fixed involving
+ synonym/deferred.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Fixed clear_mappers() behavior to better clean up after itself.
+
+ .. change::
+ :tags: orm
+ :tickets: 841
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Fixed __hash__ for association proxy- these collections are unhashable,
+ just like their mutable Python counterparts.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Added proxying of save_or_update, __contains__ and __iter__ methods for
+ scoped sessions.
+
+ .. change::
+ :tags: orm
+ :tickets: 852
+
+ fixed very hard-to-reproduce issue where by the FROM clause of Query
+ could get polluted by certain generative calls
+
+ .. change::
+ :tags: dialects
+ :tickets:
+
+ Added experimental support for MaxDB (versions >= 7.6.03.007 only).
+
+ .. change::
+ :tags: dialects
+ :tickets:
+
+ oracle will now reflect "DATE" as an OracleDateTime column, not
+ OracleDate
+
+ .. change::
+ :tags: dialects
+ :tickets: 847
+
+ added awareness of schema name in oracle table_names() function,
+ fixes metadata.reflect(schema='someschema')
+
+ .. change::
+ :tags: dialects
+ :tickets:
+
+ MSSQL anonymous labels for selection of functions made deterministic
+
+ .. change::
+ :tags: dialects
+ :tickets:
+
+ sqlite will reflect "DECIMAL" as a numeric column.
+
+ .. change::
+ :tags: dialects
+ :tickets: 828
+
+ Made access dao detection more reliable
+
+ .. change::
+ :tags: dialects
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: dialects
+ :tickets:
+
+ Added test coverage for unknown type reflection. Fixed sqlite/mysql
+ handling of type reflection for unknown types.
+
+ .. change::
+ :tags: dialects
+ :tickets:
+
+ Added REAL for mysql dialect (for folks exploiting the
+ REAL_AS_FLOAT sql mode).
+
+ .. change::
+ :tags: dialects
+ :tickets:
+
+ mysql Float, MSFloat and MSDouble constructed without arguments
+ now produce no-argument DDL, e.g.'FLOAT'.
+
+ .. change::
+ :tags: misc
+ :tickets:
+
+ Removed unused util.hash().
+
+.. changelog::
+ :version: 0.4.0
+ :released: Wed Oct 17 2007
+
+ .. change::
+ :tags:
+ :tickets:
+
+ (see 0.4.0beta1 for the start of major changes against 0.3,
+ as well as http://www.sqlalchemy.org/trac/wiki/WhatsNewIn04 )
+
+ .. change::
+ :tags:
+ :tickets: 785
+
+ Added initial Sybase support (mxODBC so far)
+
+ .. change::
+ :tags:
+ :tickets:
+
+ Added partial index support for PostgreSQL. Use the postgres_where keyword
+ on the Index.
+
+ .. change::
+ :tags:
+ :tickets: 817
+
+ string-based query param parsing/config file parser understands
+ wider range of string values for booleans
+
+ .. change::
+ :tags:
+ :tickets: 813
+
+ backref remove object operation doesn't fail if the other-side
+ collection doesn't contain the item, supports noload collections
+
+ .. change::
+ :tags:
+ :tickets: 818
+
+ removed __len__ from "dynamic" collection as it would require issuing
+ a SQL "count()" operation, thus forcing all list evaluations to issue
+ redundant SQL
+
+ .. change::
+ :tags:
+ :tickets: 816
+
+ inline optimizations added to locate_dirty() which can greatly speed up
+ repeated calls to flush(), as occurs with autoflush=True
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ Firebird has supports_sane_rowcount and supports_sane_multi_rowcount set
+ to False due to ticket #370 (right way).
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets: 795
+
+ Fixed three- and multi-level select and deferred inheritance loading
+ (i.e. abc inheritance with no select_table).
+
+ .. change::
+ :tags:
+ :tickets:
+
+ Ident passed to id_chooser in shard.py always a list.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ The no-arg ResultProxy._row_processor() is now the class attribute
+ `_process_row`.
+
+ .. change::
+ :tags:
+ :tickets: 797
+
+ Added support for returning values from inserts and updates for
+ PostgreSQL 8.2+.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets: 808
+
+ fixed sqlite reflection of BOOL/BOOLEAN
+
+ .. change::
+ :tags:
+ :tickets:
+
+ Added support for UPDATE with LIMIT on mysql.
+
+ .. change::
+ :tags:
+ :tickets: 803
+
+ null foreign key on a m2o doesn't trigger a lazyload
+
+ .. change::
+ :tags:
+ :tickets: 800
+
+ 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
+
+ .. change::
+ :tags:
+ :tickets: 806
+
+ fix to anonymous label generation of long table/column names
+
+ .. change::
+ :tags:
+ :tickets:
+
+ Firebird dialect now uses SingletonThreadPool as poolclass.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ Firebird now uses dialect.preparer to format sequences names
+
+ .. change::
+ :tags:
+ :tickets: 810
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ Added an option to the _ScopedExt mapper extension to not automatically
+ save new objects to session on object initialization.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ fixed Oracle non-ansi join syntax
+
+ .. change::
+ :tags:
+ :tickets:
+
+ PickleType and Interval types (on db not supporting it natively) are now
+ slightly faster.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ Added Float and Time types to Firebird (FBFloat and FBTime). Fixed
+ BLOB SUB_TYPE for TEXT and Binary types.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+.. changelog::
+ :version: 0.4.0beta6
+ :released: Thu Sep 27 2007
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets: 758
+
+ 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). 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).
+
+ .. change::
+ :tags:
+ :tickets:
+
+ added "FETCH" to the keywords detected by Postgres to indicate a
+ result-row holding statement (i.e. in addition to "SELECT").
+
+ .. change::
+ :tags:
+ :tickets:
+
+ Added full list of SQLite reserved keywords so that they get escaped
+ properly.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets: 560
+
+ 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)"
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets: 584, 761
+
+ Added "schema" argument to Sequence; use this with Postgres /Oracle when
+ the sequence is located in an alternate schema. Implements part of, should fix.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ Fixed reflection of the empty string for mysql enums.
+
+ .. change::
+ :tags:
+ :tickets: 794
+
+ Changed MySQL dialect to use the older LIMIT <offset>, <limit> syntax
+ instead of LIMIT <l> OFFSET <o> for folks using 3.23.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ Added 'passive_deletes="all"' flag to relation(), disables all nulling-out
+ of foreign key attributes during a flush where the parent object is
+ deleted.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ Column defaults and onupdates, executing inline, will add parenthesis for
+ subqueries and other parenthesis-requiring expressions
+
+ .. change::
+ :tags:
+ :tickets: 793
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets: 771
+
+ Fixes to ShardedSession to work with deferred columns.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.)
+
+ .. change::
+ :tags:
+ :tickets: 764
+
+ 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.. 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.
+
+ .. change::
+ :tags:
+ :tickets: 757, 768, 779, 728
+
+ Other tickets:,,.
+
+.. changelog::
+ :version: 0.4.0beta5
+ :released:
+
+ .. change::
+ :tags:
+ :tickets: 754
+
+ Connection pool fixes; the better performance of beta4 remains but fixes
+ "connection overflow" and other bugs which were present (like).
+
+ .. change::
+ :tags:
+ :tickets: 769
+
+ Fixed bugs in determining proper sync clauses from custom inherit
+ conditions.
+
+ .. change::
+ :tags:
+ :tickets: 763
+
+ Extended 'engine_from_config' coercion for QueuePool size / overflow.
+
+ .. change::
+ :tags:
+ :tickets: 748
+
+ mysql views can be reflected again.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ AssociationProxy can now take custom getters and setters.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ Fixed malfunctioning BETWEEN in orm queries.
+
+ .. change::
+ :tags:
+ :tickets: 762
+
+ Fixed OrderedProperties pickling
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets: 759
+
+ Fixed PG executemany() behavior.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ postgres reflects tables with autoincrement=False for primary key columns
+ which have no defaults.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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().
+
+ .. change::
+ :tags: tickets, fixed
+ :tickets: 742
+
+
+
+ .. change::
+ :tags: tickets, fixed
+ :tickets: 748
+
+
+
+ .. change::
+ :tags: tickets, fixed
+ :tickets: 760
+
+
+
+ .. change::
+ :tags: tickets, fixed
+ :tickets: 762
+
+
+
+ .. change::
+ :tags: tickets, fixed
+ :tickets: 763
+
+
+
+.. changelog::
+ :version: 0.4.0beta4
+ :released: Wed Aug 22 2007
+
+ .. change::
+ :tags:
+ :tickets:
+
+ Tidied up what ends up in your namespace when you 'from sqlalchemy import *':
+
+ .. change::
+ :tags:
+ :tickets:
+
+ '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.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ Internal-ish classes like ClauseElement, FromClause, NullTypeEngine,
+ etc., are also no longer imported into your namespace
+
+ .. change::
+ :tags:
+ :tickets:
+
+ The 'Smallinteger' compatiblity name (small i!) is no longer imported,
+ but remains in schema.py for now. SmallInteger (big I!) is still
+ imported.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ Fix to bind param processing such that "False" values (like blank strings)
+ still get processed/encoded.
+
+ .. change::
+ :tags:
+ :tickets: 752
+
+ Fix to select() "generative" behavior, such that calling column(),
+ select_from(), correlate(), and with_prefix() does not modify the
+ original select object
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ Added session.prune(), trims away instances cached in a session that
+ are no longer referenced elsewhere. (A utility for strong-ref
+ identity maps).
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets: 735
+
+ Modified SQL operator functions to be module-level operators,
+ allowing SQL expressions to be pickleable.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ Small adjustment to mapper class.__init__ to allow for Py2.6
+ object.__init__() behavior.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ Fixed 'prefix' argument for select()
+
+ .. change::
+ :tags:
+ :tickets:
+
+ Connection.begin() no longer accepts nested=True, this logic is now
+ all in begin_nested().
+
+ .. change::
+ :tags:
+ :tickets:
+
+ Fixes to new "dynamic" relation loader involving cascades
+
+ .. change::
+ :tags: tickets, fixed
+ :tickets: 735
+
+
+
+ .. change::
+ :tags: tickets, fixed
+ :tickets: 752
+
+
+
+.. changelog::
+ :version: 0.4.0beta3
+ :released: Thu Aug 16 2007
+
+ .. change::
+ :tags:
+ :tickets:
+
+ SQL types optimization:
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ General performance improvement of result set iteration is around 10-20%.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ Hooks added throughout base/sql/defaults to optimize the calling of bind
+ aram/result processors so that method call overhead is minimized.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ Support added for executemany() scenarios such that unneeded "last row id"
+ logic doesn't kick in, parameters aren't excessively traversed.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ Added 'inherit_foreign_keys' arg to mapper().
+
+ .. change::
+ :tags:
+ :tickets:
+
+ Added support for string date passthrough in sqlite.
+
+ .. change::
+ :tags: tickets, fixed
+ :tickets: 738
+
+
+
+ .. change::
+ :tags: tickets, fixed
+ :tickets: 739
+
+
+
+ .. change::
+ :tags: tickets, fixed
+ :tickets: 743
+
+
+
+ .. change::
+ :tags: tickets, fixed
+ :tickets: 744
+
+
+
+.. changelog::
+ :version: 0.4.0beta2
+ :released: Tue Aug 14 2007
+
+ .. change::
+ :tags: oracle, improvements.
+ :tickets:
+
+ Auto-commit after LOAD DATA INFILE for mysql.
+
+ .. change::
+ :tags: oracle, improvements.
+ :tickets:
+
+ A rudimental SessionExtension class has been added, allowing user-defined
+ functionality to take place at flush(), commit(), and rollback() boundaries.
+
+ .. change::
+ :tags: oracle, improvements.
+ :tickets:
+
+ Added engine_from_config() function for helping to create_engine() from an
+ .ini style config.
+
+ .. change::
+ :tags: oracle, improvements.
+ :tickets:
+
+ base_mapper() becomes a plain attribute.
+
+ .. change::
+ :tags: oracle, improvements.
+ :tickets:
+
+ session.execute() and scalar() can search for a Table with which to bind from
+ using the given ClauseElement.
+
+ .. change::
+ :tags: oracle, improvements.
+ :tickets:
+
+ Session automatically extrapolates tables from mappers with binds, also uses
+ base_mapper so that inheritance hierarchies bind automatically.
+
+ .. change::
+ :tags: oracle, improvements.
+ :tickets:
+
+ Moved ClauseVisitor traversal back to inlined non-recursive.
+
+ .. change::
+ :tags: tickets, fixed
+ :tickets: 730
+
+
+
+ .. change::
+ :tags: tickets, fixed
+ :tickets: 732
+
+
+
+ .. change::
+ :tags: tickets, fixed
+ :tickets: 733
+
+
+
+ .. change::
+ :tags: tickets, fixed
+ :tickets: 734
+
+
+
+.. changelog::
+ :version: 0.4.0beta1
+ :released: Sun Aug 12 2007
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Speed! Along with recent speedups to ResultProxy, total number of function
+ calls significantly reduced for large loads.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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).
+
+ .. change::
+ :tags: orm
+ :tickets: 213
+
+ New collection_class api and implementation. 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ __setitem__-like assignments now fire remove events for the existing
+ value, if any.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ AttributeExtension moved to interfaces, and .delete is now .remove The
+ event method signature has also been swapped around.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Major overhaul for Query:
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets: 643
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Removed ancient query.select_by_attributename() capability.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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
+
+ .. change::
+ :tags: orm
+ :tickets: 660
+
+ Added query.populate_existing(), marks the query to reload all
+ attributes and collections of all instances touched in the query,
+ including eagerly-loaded entities.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Added eagerload_all(), allows eagerload_all('x.y.z') to specify eager
+ loading of all properties in the given path.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Major overhaul for Session:
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ SessionTransaction removed from "public" API. You now can call begin()/
+ commit()/rollback() on the Session itself.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Session also supports SAVEPOINT transactions; call begin_nested().
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Session supports two-phase commit behavior when vertically or
+ horizontally partitioning (i.e., using more than one engine). Use
+ twophase=True.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Added new "binds" argument to Session to support configuration of
+ multiple binds with sessionmaker() function.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ A rudimental SessionExtension class has been added, allowing
+ user-defined functionality to take place at flush(), commit(), and
+ rollback() boundaries.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets: 618
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets: 659
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets: 211
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Improved support for custom column_property() attributes which feature
+ correlated subqueries, works better with eager loading now.
+
+ .. change::
+ :tags: orm
+ :tickets: 611
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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'
+
+ .. change::
+ :tags: orm
+ :tickets: 696
+
+ It's now possible to map only a subset of available selectable columns
+ onto mapper properties, using include_columns/exclude_columns..
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Added undefer_group() MapperOption, sets a set of "deferred" columns
+ joined by a "group" to load as "undeferred".
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ 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".
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ 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).
+
+ .. change::
+ :tags: transactions
+ :tickets:
+
+ Added context manager (with statement) support for transactions.
+
+ .. change::
+ :tags: transactions
+ :tickets:
+
+ Added support for two phase commit, works with mysql and postgres so far.
+
+ .. change::
+ :tags: transactions
+ :tickets:
+
+ Added a subtransaction implementation that uses savepoints.
+
+ .. change::
+ :tags: transactions
+ :tickets:
+
+ Added support for savepoints.
+
+ .. change::
+ :tags: metadata
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: metadata
+ :tickets:
+
+ DynamicMetaData has been renamed to ThreadLocalMetaData
+
+ .. change::
+ :tags: metadata
+ :tickets:
+
+ The ThreadLocalMetaData constructor now takes no arguments.
+
+ .. change::
+ :tags: metadata
+ :tickets:
+
+ BoundMetaData has been removed- regular MetaData is equivalent
+
+ .. change::
+ :tags: metadata
+ :tickets: 646
+
+ 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.
+
+ .. change::
+ :tags: metadata
+ :tickets: 475
+
+ 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.
+
+ .. change::
+ :tags: metadata
+ :tickets:
+
+ "Anonymous" alias and label names are now generated at SQL compilation
+ time in a completely deterministic fashion... no more random hex IDs
+
+ .. change::
+ :tags: metadata
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: metadata
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: metadata
+ :tickets: 569, 52
+
+ 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
+
+ .. change::
+ :tags: metadata
+ :tickets:
+
+ select(scalar=True) argument is deprecated; use select(..).as_scalar().
+ The resulting object obeys the full "column" interface and plays better
+ within expressions.
+
+ .. change::
+ :tags: metadata
+ :tickets: 504
+
+ Added select().with_prefix('foo') allowing any set of keywords to be
+ placed before the columns clause of the SELECT
+
+ .. change::
+ :tags: metadata
+ :tickets: 686
+
+ Added array slice support to row[<index>]
+
+ .. change::
+ :tags: metadata
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: metadata
+ :tickets:
+
+ 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".
+
+ .. change::
+ :tags: metadata
+ :tickets: 559
+
+ 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. The connection used for the execution is available as well
+ so that you can pre-execute statements.
+
+ .. change::
+ :tags: metadata
+ :tickets:
+
+ Added "explcit" create/drop/execute support for sequences (i.e. you can
+ pass a "connectable" to each of those methods on Sequence).
+
+ .. change::
+ :tags: metadata
+ :tickets:
+
+ Better quoting of identifiers when manipulating schemas.
+
+ .. change::
+ :tags: metadata
+ :tickets:
+
+ Standardized the behavior for table reflection where types can't be
+ located; NullType is substituted instead, warning is raised.
+
+ .. change::
+ :tags: metadata
+ :tickets: 606
+
+ ColumnCollection (i.e. the 'c' attribute on tables) follows dictionary
+ semantics for "__contains__"
+
+ .. change::
+ :tags: engines
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: engines
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: engines
+ :tickets:
+
+ Connections gain a .properties collection, with contents scoped to the
+ lifetime of the underlying DBAPI connection
+
+ .. change::
+ :tags: engines
+ :tickets:
+
+ Removed auto_close_cursors and disallow_open_cursors arguments from Pool;
+ reduces overhead as cursors are normally closed by ResultProxy and
+ Connection.
+
+ .. change::
+ :tags: extensions
+ :tickets:
+
+ proxyengine is temporarily removed, pending an actually working
+ replacement.
+
+ .. change::
+ :tags: extensions
+ :tickets:
+
+ 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().
+
+ .. change::
+ :tags: mysql
+ :tickets:
+
+ Table and column names loaded via reflection are now Unicode.
+
+ .. change::
+ :tags: mysql
+ :tickets:
+
+ All standard column types are now supported, including SET.
+
+ .. change::
+ :tags: mysql
+ :tickets:
+
+ Table reflection can now be performed in as little as one round-trip.
+
+ .. change::
+ :tags: mysql
+ :tickets:
+
+ ANSI and ANSI_QUOTES sql modes are now supported.
+
+ .. change::
+ :tags: mysql
+ :tickets:
+
+ Indexes are now reflected.
+
+ .. change::
+ :tags: postgres
+ :tickets:
+
+ Added PGArray datatype for using postgres array datatypes.
+
+ .. change::
+ :tags: oracle
+ :tickets: 507
+
+ 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.
--- /dev/null
+
+==============
+0.5 Changelog
+==============
+
+
+.. changelog::
+ :version: 0.5.9
+ :released:
+
+ .. change::
+ :tags: sql
+ :tickets: 1661
+
+ Fixed erroneous self_group() call in expression package.
+
+.. changelog::
+ :version: 0.5.8
+ :released: Sat Jan 16 2010
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ The copy() method on Column now supports uninitialized,
+ unnamed Column objects. This allows easy creation of
+ declarative helpers which place common columns on multiple
+ subclasses.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Default generators like Sequence() translate correctly
+ across a copy() operation.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Sequence() and other DefaultGenerator objects are accepted
+ as the value for the "default" and "onupdate" keyword
+ arguments of Column, in addition to being accepted
+ positionally.
+
+ .. change::
+ :tags: sql
+ :tickets: 1568, 1617
+
+ Fixed a column arithmetic bug that affected column
+ correspondence for cloned selectables which contain
+ free-standing column expressions. This bug is
+ generally only noticeable when exercising newer
+ ORM behavior only availble in 0.6 via,
+ but is more correct at the SQL expression level
+ as well.
+
+ .. change::
+ :tags: postgresql
+ :tickets: 1647
+
+ The extract() function, which was slightly improved in
+ 0.5.7, needed a lot more work to generate the correct
+ typecast (the typecasts appear to be necessary in PG's
+ EXTRACT quite a lot of the time). The typecast is
+ now generated using a rule dictionary based
+ on PG's documentation for date/time/interval arithmetic.
+ It also accepts text() constructs again, which was broken
+ in 0.5.7.
+
+ .. change::
+ :tags: firebird
+ :tickets: 1646
+
+ Recognize more errors as disconnections.
+
+.. changelog::
+ :version: 0.5.7
+ :released: Sat Dec 26 2009
+
+ .. change::
+ :tags: orm
+ :tickets: 1543
+
+ contains_eager() now works with the automatically
+ generated subquery that results when you say
+ "query(Parent).join(Parent.somejoinedsubclass)", i.e.
+ when Parent joins to a joined-table-inheritance subclass.
+ Previously contains_eager() would erroneously add the
+ subclass table to the query separately producing a
+ cartesian product. An example is in the ticket
+ description.
+
+ .. change::
+ :tags: orm
+ :tickets: 1553
+
+ query.options() now only propagate to loaded objects
+ for potential further sub-loads only for options where
+ such behavior is relevant, keeping
+ various unserializable options like those generated
+ by contains_eager() out of individual instance states.
+
+ .. change::
+ :tags: orm
+ :tickets: 1054
+
+ Session.execute() now locates table- and
+ mapper-specific binds based on a passed
+ in expression which is an insert()/update()/delete()
+ construct.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Session.merge() now properly overwrites a many-to-one or
+ uselist=False attribute to None if the attribute
+ is also None in the given object to be merged.
+
+ .. change::
+ :tags: orm
+ :tickets: 1618
+
+ Fixed a needless select which would occur when merging
+ transient objects that contained a null primary key
+ identifier.
+
+ .. change::
+ :tags: orm
+ :tickets: 1585
+
+ Mutable collection passed to the "extension" attribute
+ of relation(), column_property() etc. will not be mutated
+ or shared among multiple instrumentation calls, preventing
+ duplicate extensions, such as backref populators,
+ from being inserted into the list.
+
+ .. change::
+ :tags: orm
+ :tickets: 1504
+
+ Fixed the call to get_committed_value() on CompositeProperty.
+
+ .. change::
+ :tags: orm
+ :tickets: 1602
+
+ Fixed bug where Query would crash if a join() with no clear
+ "left" side were called when a non-mapped column entity
+ appeared in the columns list.
+
+ .. change::
+ :tags: orm
+ :tickets: 1616, 1480
+
+ Fixed bug whereby composite columns wouldn't load properly
+ when configured on a joined-table subclass, introduced in
+ version 0.5.6 as a result of the fix for. thx to Scott Torborg.
+
+ .. change::
+ :tags: orm
+ :tickets: 1556
+
+ The "use get" behavior of many-to-one relations, i.e. that a
+ lazy load will fallback to the possibly cached query.get()
+ value, now works across join conditions where the two compared
+ types are not exactly the same class, but share the same
+ "affinity" - i.e. Integer and SmallInteger. Also allows
+ combinations of reflected and non-reflected types to work
+ with 0.5 style type reflection, such as PGText/Text (note 0.6
+ reflects types as their generic versions).
+
+ .. change::
+ :tags: orm
+ :tickets: 1436
+
+ Fixed bug in query.update() when passing Cls.attribute
+ as keys in the value dict and using synchronize_session='expire'
+ ('fetch' in 0.6).
+
+ .. change::
+ :tags: sql
+ :tickets: 1603
+
+ Fixed bug in two-phase transaction whereby commit() method
+ didn't set the full state which allows subsequent close()
+ call to succeed.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Fixed the "numeric" paramstyle, which apparently is the
+ default paramstyle used by Informixdb.
+
+ .. change::
+ :tags: sql
+ :tickets: 1574
+
+ Repeat expressions in the columns clause of a select
+ are deduped based on the identity of each clause element,
+ not the actual string. This allows positional
+ elements to render correctly even if they all render
+ identically, such as "qmark" style bind parameters.
+
+ .. change::
+ :tags: sql
+ :tickets: 1632
+
+ The cursor associated with connection pool connections
+ (i.e. _CursorFairy) now proxies `__iter__()` to the
+ underlying cursor correctly.
+
+ .. change::
+ :tags: sql
+ :tickets: 1556
+
+ types now support an "affinity comparison" operation, i.e.
+ that an Integer/SmallInteger are "compatible", or
+ a Text/String, PickleType/Binary, etc. Part of.
+
+ .. change::
+ :tags: sql
+ :tickets: 1641
+
+ Fixed bug preventing alias() of an alias() from being
+ cloned or adapted (occurs frequently in ORM operations).
+
+ .. change::
+ :tags: sqlite
+ :tickets: 1439
+
+ sqlite dialect properly generates CREATE INDEX for a table
+ that is in an alternate schema.
+
+ .. change::
+ :tags: postgresql
+ :tickets: 1085
+
+ Added support for reflecting the DOUBLE PRECISION type,
+ via a new postgres.PGDoublePrecision object.
+ This is postgresql.DOUBLE_PRECISION in 0.6.
+
+ .. change::
+ :tags: postgresql
+ :tickets: 460
+
+ Added support for reflecting the INTERVAL YEAR TO MONTH
+ and INTERVAL DAY TO SECOND syntaxes of the INTERVAL
+ type.
+
+ .. change::
+ :tags: postgresql
+ :tickets: 1576
+
+ Corrected the "has_sequence" query to take current schema,
+ or explicit sequence-stated schema, into account.
+
+ .. change::
+ :tags: postgresql
+ :tickets: 1611
+
+ Fixed the behavior of extract() to apply operator
+ precedence rules to the "::" operator when applying
+ the "timestamp" cast - ensures proper parenthesization.
+
+ .. change::
+ :tags: mssql
+ :tickets: 1561
+
+ Changed the name of TrustedConnection to
+ Trusted_Connection when constructing pyodbc connect
+ arguments
+
+ .. change::
+ :tags: oracle
+ :tickets: 1637
+
+ The "table_names" dialect function, used by MetaData
+ .reflect(), omits "index overflow tables", a system
+ table generated by Oracle when "index only tables"
+ with overflow are used. These tables aren't accessible
+ via SQL and can't be reflected.
+
+ .. change::
+ :tags: ext
+ :tickets: 1570, 1523
+
+ A column can be added to a joined-table declarative
+ superclass after the class has been constructed
+ (i.e. via class-level attribute assignment), and
+ the column will be propagated down to
+ subclasses. This is the reverse
+ situation as that of, fixed in 0.5.6.
+
+ .. change::
+ :tags: ext
+ :tickets: 1491
+
+ Fixed a slight inaccuracy in the sharding example.
+ Comparing equivalence of columns in the ORM is best
+ accomplished using col1.shares_lineage(col2).
+
+ .. change::
+ :tags: ext
+ :tickets: 1606
+
+ Removed unused `load()` method from ShardedQuery.
+
+.. changelog::
+ :version: 0.5.6
+ :released: Sat Sep 12 2009
+
+ .. change::
+ :tags: orm
+ :tickets: 1300
+
+ Fixed bug whereby inheritance discriminator part of a
+ composite primary key would fail on updates.
+ Continuation of.
+
+ .. change::
+ :tags: orm
+ :tickets: 1507
+
+ Fixed bug which disallowed one side of a many-to-many
+ bidirectional reference to declare itself as "viewonly"
+
+ .. change::
+ :tags: orm
+ :tickets: 1526
+
+ Added an assertion that prevents a @validates function
+ or other AttributeExtension from loading an unloaded
+ collection such that internal state may be corrupted.
+
+ .. change::
+ :tags: orm
+ :tickets: 1519
+
+ Fixed bug which prevented two entities from mutually
+ replacing each other's primary key values within a single
+ flush() for some orderings of operations.
+
+ .. change::
+ :tags: orm
+ :tickets: 1485
+
+ Fixed an obscure issue whereby a joined-table subclass
+ with a self-referential eager load on the base class
+ would populate the related object's "subclass" table with
+ data from the "subclass" table of the parent.
+
+ .. change::
+ :tags: orm
+ :tickets: 1477
+
+ relations() now have greater ability to be "overridden",
+ meaning a subclass that explicitly specifies a relation()
+ overriding that of the parent class will be honored
+ during a flush. This is currently to support
+ many-to-many relations from concrete inheritance setups.
+ Outside of that use case, YMMV.
+
+ .. change::
+ :tags: orm
+ :tickets: 1483
+
+ Squeezed a few more unnecessary "lazy loads" out of
+ relation(). When a collection is mutated, many-to-one
+ backrefs on the other side will not fire off to load
+ the "old" value, unless "single_parent=True" is set.
+ A direct assignment of a many-to-one still loads
+ the "old" value in order to update backref collections
+ on that value, which may be present in the session
+ already, thus maintaining the 0.5 behavioral contract.
+
+ .. change::
+ :tags: orm
+ :tickets: 1480
+
+ Fixed bug whereby a load/refresh of joined table
+ inheritance attributes which were based on
+ column_property() or similar would fail to evaluate.
+
+ .. change::
+ :tags: orm
+ :tickets: 1488
+
+ Improved support for MapperProperty objects overriding
+ that of an inherited mapper for non-concrete
+ inheritance setups - attribute extensions won't randomly
+ collide with each other.
+
+ .. change::
+ :tags: orm
+ :tickets: 1487
+
+ UPDATE and DELETE do not support ORDER BY, LIMIT, OFFSET,
+ etc. in standard SQL. Query.update() and Query.delete()
+ now raise an exception if any of limit(), offset(),
+ order_by(), group_by(), or distinct() have been
+ called.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Added AttributeExtension to sqlalchemy.orm.__all__
+
+ .. change::
+ :tags: orm
+ :tickets: 1476
+
+ Improved error message when query() is called with
+ a non-SQL /entity expression.
+
+ .. change::
+ :tags: orm
+ :tickets: 1440
+
+ Using False or 0 as a polymorphic discriminator now
+ works on the base class as well as a subclass.
+
+ .. change::
+ :tags: orm
+ :tickets: 1424
+
+ Added enable_assertions(False) to Query which disables
+ the usual assertions for expected state - used
+ by Query subclasses to engineer custom state.. See
+ http://www.sqlalchemy.org/trac/wiki/UsageRecipes/PreFilteredQuery
+ for an example.
+
+ .. change::
+ :tags: orm
+ :tickets: 1501
+
+ Fixed recursion issue which occured if a mapped object's
+ `__len__()` or `__nonzero__()` method resulted in state
+ changes.
+
+ .. change::
+ :tags: orm
+ :tickets: 1506
+
+ Fixed incorrect exception raise in
+ Weak/StrongIdentityMap.add()
+
+ .. change::
+ :tags: orm
+ :tickets: 1522
+
+ Fixed the error message for "could not find a FROM clause"
+ in query.join() which would fail to issue correctly
+ if the query was against a pure SQL construct.
+
+ .. change::
+ :tags: orm
+ :tickets: 1486
+
+ Fixed a somewhat hypothetical issue which would result
+ in the wrong primary key being calculated for a mapper
+ using the old polymorphic_union function - but this
+ is old stuff.
+
+ .. change::
+ :tags: sql
+ :tickets: 1373
+
+ Fixed column.copy() to copy defaults and onupdates.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Fixed a bug in extract() introduced in 0.5.4 whereby
+ the string "field" argument was getting treated as a
+ ClauseElement, causing various errors within more
+ complex SQL transformations.
+
+ .. change::
+ :tags: sql
+ :tickets: 1420
+
+ Unary expressions such as DISTINCT propagate their
+ type handling to result sets, allowing conversions like
+ unicode and such to take place.
+
+ .. change::
+ :tags: sql
+ :tickets: 1482
+
+ Fixed bug in Table and Column whereby passing empty
+ dict for "info" argument would raise an exception.
+
+ .. change::
+ :tags: oracle
+ :tickets: 1309
+
+ Backported 0.6 fix for Oracle alias names not getting
+ truncated.
+
+ .. change::
+ :tags: ext
+ :tickets: 1446
+
+ The collection proxies produced by associationproxy are now
+ pickleable. A user-defined proxy_factory however
+ is still not pickleable unless it defines __getstate__
+ and __setstate__.
+
+ .. change::
+ :tags: ext
+ :tickets: 1468
+
+ Declarative will raise an informative exception if
+ __table_args__ is passed as a tuple with no dict argument.
+ Improved documentation.
+
+ .. change::
+ :tags: ext
+ :tickets: 1527
+
+ Table objects declared in the MetaData can now be used
+ in string expressions sent to primaryjoin/secondaryjoin/
+ secondary - the name is pulled from the MetaData of the
+ declarative base.
+
+ .. change::
+ :tags: ext
+ :tickets: 1523
+
+ A column can be added to a joined-table subclass after
+ the class has been constructed (i.e. via class-level
+ attribute assignment). The column is added to the underlying
+ Table as always, but now the mapper will rebuild its
+ "join" to include the new column, instead of raising
+ an error about "no such column, use column_property()
+ instead".
+
+ .. change::
+ :tags: test
+ :tickets:
+
+ Added examples into the test suite so they get exercised
+ regularly and cleaned up a couple deprecation warnings.
+
+.. changelog::
+ :version: 0.5.5
+ :released: Mon Jul 13 2009
+
+ .. change::
+ :tags: general
+ :tickets: 970
+
+ unit tests have been migrated from unittest to nose. See
+ README.unittests for information on how to run the tests.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ The "foreign_keys" argument of relation() will now propagate
+ automatically to the backref in the same way that primaryjoin
+ and secondaryjoin do. For the extremely rare use case where
+ the backref of a relation() has intentionally different
+ "foreign_keys" configured, both sides now need to be
+ configured explicity (if they do in fact require this setting,
+ see the next note...).
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ ...the only known (and really, really rare) use case where a
+ different foreign_keys setting was used on the
+ forwards/backwards side, a composite foreign key that
+ partially points to its own columns, has been enhanced such
+ that the fk->itself aspect of the relation won't be used to
+ determine relation direction.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Session.mapper is now *deprecated*.
+
+ Call session.add() if you'd like a free-standing object to be
+ part of your session. Otherwise, a DIY version of
+ Session.mapper is now documented at
+ http://www.sqlalchemy.org/trac/wiki/UsageRecipes/SessionAwareMapper
+ The method will remain deprecated throughout 0.6.
+
+ .. change::
+ :tags: orm
+ :tickets: 1431
+
+ Fixed Query being able to join() from individual columns of a
+ joined-table subclass entity, i.e. query(SubClass.foo,
+ SubcClass.bar).join(<anything>). In most cases, an error
+ "Could not find a FROM clause to join from" would be
+ raised. In a few others, the result would be returned in terms
+ of the base class rather than the subclass - so applications
+ which relied on this erroneous result need to be
+ adjusted.
+
+ .. change::
+ :tags: orm
+ :tickets: 1461
+
+ Fixed a bug involving contains_eager(), which would apply
+ itself to a secondary (i.e. lazy) load in a particular rare
+ case, producing cartesian products. improved the targeting of
+ query.options() on secondary loads overall.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Fixed bug introduced in 0.5.4 whereby Composite types fail
+ when default-holding columns are flushed.
+
+ .. change::
+ :tags: orm
+ :tickets: 1426
+
+ Fixed another 0.5.4 bug whereby mutable attributes
+ (i.e. PickleType) wouldn't be deserialized correctly when the
+ whole object was serialized.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Fixed bug whereby session.is_modified() would raise an
+ exception if any synonyms were in use.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Fixed potential memory leak whereby previously pickled objects
+ placed back in a session would not be fully garbage collected
+ unless the Session were explicitly closed out.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Fixed bug whereby list-based attributes, like pickletype and
+ PGArray, failed to be merged() properly.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Repaired non-working attributes.set_committed_value function.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Trimmed the pickle format for InstanceState which should
+ further reduce the memory footprint of pickled instances. The
+ format should be backwards compatible with that of 0.5.4 and
+ previous.
+
+ .. change::
+ :tags: orm
+ :tickets: 1463
+
+ sqlalchemy.orm.join and sqlalchemy.orm.outerjoin are now
+ added to __all__ in sqlalchemy.orm.*.
+
+ .. change::
+ :tags: orm
+ :tickets: 1458
+
+ Fixed bug where Query exception raise would fail when
+ a too-short composite primary key value were passed to
+ get().
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Removed an obscure feature of execute() (including connection,
+ engine, Session) whereby a bindparam() construct can be sent
+ as a key to the params dictionary. This usage is undocumented
+ and is at the core of an issue whereby the bindparam() object
+ created implicitly by a text() construct may have the same
+ hash value as a string placed in the params dictionary and may
+ result in an inappropriate match when computing the final bind
+ parameters. Internal checks for this condition would add
+ significant latency to the critical task of parameter
+ rendering, so the behavior is removed. This is a backwards
+ incompatible change for any application that may have been
+ using this feature, however the feature has never been
+ documented.
+
+ .. change::
+ :tags: engine/pool
+ :tickets:
+
+ Implemented recreate() for StaticPool.
+
+.. changelog::
+ :version: 0.5.4p2
+ :released: Tue May 26 2009
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Repaired the printing of SQL exceptions which are not
+ based on parameters or are not executemany() style.
+
+ .. change::
+ :tags: postgresql
+ :tickets:
+
+ Deprecated the hardcoded TIMESTAMP function, which when
+ used as func.TIMESTAMP(value) would render "TIMESTAMP value".
+ This breaks on some platforms as PostgreSQL doesn't allow
+ bind parameters to be used in this context. The hard-coded
+ uppercase is also inappropriate and there's lots of other
+ PG casts that we'd need to support. So instead, use
+ text constructs i.e. select(["timestamp '12/05/09'"]).
+
+.. changelog::
+ :version: 0.5.4p1
+ :released: Mon May 18 2009
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Fixed an attribute error introduced in 0.5.4 which would
+ occur when merge() was used with an incomplete object.
+
+.. changelog::
+ :version: 0.5.4
+ :released: Sun May 17 2009
+
+ .. change::
+ :tags: orm
+ :tickets: 1398
+
+ Significant performance enhancements regarding Sessions/flush()
+ in conjunction with large mapper graphs, large numbers of
+ objects:
+
+ - Removed all* O(N) scanning behavior from the flush() process,
+ i.e. operations that were scanning the full session,
+ including an extremely expensive one that was erroneously
+ assuming primary key values were changing when this
+ was not the case.
+
+ * one edge case remains which may invoke a full scan,
+ if an existing primary key attribute is modified
+ to a new value.
+
+ - The Session's "weak referencing" behavior is now *full* -
+ no strong references whatsoever are made to a mapped object
+ or related items/collections in its __dict__. Backrefs and
+ other cycles in objects no longer affect the Session's ability
+ to lose all references to unmodified objects. Objects with
+ pending changes still are maintained strongly until flush.
+
+
+ The implementation also improves performance by moving
+ the "resurrection" process of garbage collected items
+ to only be relevant for mappings that map "mutable"
+ attributes (i.e. PickleType, composite attrs). This removes
+ overhead from the gc process and simplifies internal
+ behavior.
+
+ If a "mutable" attribute change is the sole change on an object
+ which is then dereferenced, the mapper will not have access to
+ other attribute state when the UPDATE is issued. This may present
+ itself differently to some MapperExtensions.
+
+ The change also affects the internal attribute API, but not
+ the AttributeExtension interface nor any of the publically
+ documented attribute functions.
+
+ - The unit of work no longer genererates a graph of "dependency"
+ processors for the full graph of mappers during flush(), instead
+ creating such processors only for those mappers which represent
+ objects with pending changes. This saves a tremendous number
+ of method calls in the context of a large interconnected
+ graph of mappers.
+
+ - Cached a wasteful "table sort" operation that previously
+ occured multiple times per flush, also removing significant
+ method call count from flush().
+
+ - Other redundant behaviors have been simplified in
+ mapper._save_obj().
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Modified query_cls on DynamicAttributeImpl to accept a full
+ mixin version of the AppenderQuery, which allows subclassing
+ the AppenderMixin.
+
+ .. change::
+ :tags: orm
+ :tickets: 1300
+
+ The "polymorphic discriminator" column may be part of a
+ primary key, and it will be populated with the correct
+ discriminator value.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Fixed the evaluator not being able to evaluate IS NULL clauses.
+
+ .. change::
+ :tags: orm
+ :tickets: 1352
+
+ Fixed the "set collection" function on "dynamic" relations to
+ initiate events correctly. Previously a collection could only
+ be assigned to a pending parent instance, otherwise modified
+ events would not be fired correctly. Set collection is now
+ compatible with merge(), fixes.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Allowed pickling of PropertyOption objects constructed with
+ instrumented descriptors; previously, pickle errors would occur
+ when pickling an object which was loaded with a descriptor-based
+ option, such as query.options(eagerload(MyClass.foo)).
+
+ .. change::
+ :tags: orm
+ :tickets: 1357
+
+ Lazy loader will not use get() if the "lazy load" SQL clause
+ matches the clause used by get(), but contains some parameters
+ hardcoded. Previously the lazy strategy would fail with the
+ get(). Ideally get() would be used with the hardcoded
+ parameters but this would require further development.
+
+ .. change::
+ :tags: orm
+ :tickets: 1391
+
+ MapperOptions and other state associated with query.options()
+ is no longer bundled within callables associated with each
+ lazy/deferred-loading attribute during a load.
+ The options are now associated with the instance's
+ state object just once when it's populated. This removes
+ the need in most cases for per-instance/attribute loader
+ objects, improving load speed and memory overhead for
+ individual instances.
+
+ .. change::
+ :tags: orm
+ :tickets: 1360
+
+ Fixed another location where autoflush was interfering
+ with session.merge(). autoflush is disabled completely
+ for the duration of merge() now.
+
+ .. change::
+ :tags: orm
+ :tickets: 1406
+
+ Fixed bug which prevented "mutable primary key" dependency
+ logic from functioning properly on a one-to-one
+ relation().
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Fixed bug in relation(), introduced in 0.5.3,
+ whereby a self referential relation
+ from a base class to a joined-table subclass would
+ not configure correctly.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Fixed obscure mapper compilation issue when inheriting
+ mappers are used which would result in un-initialized
+ attributes.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Fixed documentation for session weak_identity_map -
+ the default value is True, indicating a weak
+ referencing map in use.
+
+ .. change::
+ :tags: orm
+ :tickets: 1376
+
+ Fixed a unit of work issue whereby the foreign
+ key attribute on an item contained within a collection
+ owned by an object being deleted would not be set to
+ None if the relation() was self-referential.
+
+ .. change::
+ :tags: orm
+ :tickets: 1378
+
+ Fixed Query.update() and Query.delete() failures with eagerloaded
+ relations.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ It is now an error to specify both columns of a binary primaryjoin
+ condition in the foreign_keys or remote_side collection. Whereas
+ previously it was just nonsensical, but would succeed in a
+ non-deterministic way.
+
+ .. change::
+ :tags: ticket: 594, 1341, schema
+ :tickets:
+
+ Added a quote_schema() method to the IdentifierPreparer class
+ so that dialects can override how schemas get handled. This
+ enables the MSSQL dialect to treat schemas as multipart
+ identifiers, such as 'database.owner'.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Back-ported the "compiler" extension from SQLA 0.6. This
+ is a standardized interface which allows the creation of custom
+ ClauseElement subclasses and compilers. In particular it's
+ handy as an alternative to text() when you'd like to
+ build a construct that has database-specific compilations.
+ See the extension docs for details.
+
+ .. change::
+ :tags: sql
+ :tickets: 1413
+
+ Exception messages are truncated when the list of bound
+ parameters is larger than 10, preventing enormous
+ multi-page exceptions from filling up screens and logfiles
+ for large executemany() statements.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ ``sqlalchemy.extract()`` is now dialect sensitive and can
+ extract components of timestamps idiomatically across the
+ supported databases, including SQLite.
+
+ .. change::
+ :tags: sql
+ :tickets: 1353
+
+ Fixed __repr__() and other _get_colspec() methods on
+ ForeignKey constructed from __clause_element__() style
+ construct (i.e. declarative columns).
+
+ .. change::
+ :tags: mysql
+ :tickets: 1405
+
+ Reflecting a FOREIGN KEY construct will take into account
+ a dotted schema.tablename combination, if the foreign key
+ references a table in a remote schema.
+
+ .. change::
+ :tags: mssql
+ :tickets:
+
+ Modified how savepoint logic works to prevent it from
+ stepping on non-savepoint oriented routines. Savepoint
+ support is still very experimental.
+
+ .. change::
+ :tags: mssql
+ :tickets: 1310
+
+ Added in reserved words for MSSQL that covers version 2008
+ and all prior versions.
+
+ .. change::
+ :tags: mssql
+ :tickets: 1343
+
+ Corrected problem with information schema not working with a
+ binary collation based database. Cleaned up information schema
+ since it is only used by mssql now.
+
+ .. change::
+ :tags: sqlite
+ :tickets: 1402
+
+ Corrected the SLBoolean type so that it properly treats only 1
+ as True.
+
+ .. change::
+ :tags: sqlite
+ :tickets: 1273
+
+ Corrected the float type so that it correctly maps to a
+ SLFloat type when being reflected.
+
+ .. change::
+ :tags: extensions
+ :tickets: 1379
+
+ Fixed adding of deferred or other column properties to a
+ declarative class.
+
+.. changelog::
+ :version: 0.5.3
+ :released: Tue Mar 24 2009
+
+ .. change::
+ :tags: orm
+ :tickets: 1315
+
+ The "objects" argument to session.flush() is deprecated.
+ State which represents the linkage between a parent and
+ child object does not support "flushed" status on
+ one side of the link and not the other, so supporting
+ this operation leads to misleading results.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Query now implements __clause_element__() which produces
+ its selectable, which means a Query instance can be accepted
+ in many SQL expressions, including col.in_(query),
+ union(query1, query2), select([foo]).select_from(query),
+ etc.
+
+ .. change::
+ :tags: orm
+ :tickets: 1337
+
+ Query.join() can now construct multiple FROM clauses, if
+ needed. Such as, query(A, B).join(A.x).join(B.y)
+ might say SELECT A.*, B.* FROM A JOIN X, B JOIN Y.
+ Eager loading can also tack its joins onto those
+ multiple FROM clauses.
+
+ .. change::
+ :tags: orm
+ :tickets: 1347
+
+ Fixed bug in dynamic_loader() where append/remove events
+ after construction time were not being propagated to the
+ UOW to pick up on flush().
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Fixed bug where column_prefix wasn't being checked before
+ not mapping an attribute that already had class-level
+ name present.
+
+ .. change::
+ :tags: orm
+ :tickets: 1315
+
+ a session.expire() on a particular collection attribute
+ will clear any pending backref additions as well, so that
+ the next access correctly returns only what was present
+ in the database. Presents some degree of a workaround for, although we are considering removing the
+ flush([objects]) feature altogether.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Session.scalar() now converts raw SQL strings to text()
+ the same way Session.execute() does and accepts same
+ alternative **kw args.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ improvements to the "determine direction" logic of
+ relation() such that the direction of tricky situations
+ like mapper(A.join(B)) -> relation-> mapper(B) can be
+ determined.
+
+ .. change::
+ :tags: orm
+ :tickets: 1306
+
+ When flushing partial sets of objects using session.flush([somelist]),
+ pending objects which remain pending after the operation won't
+ inadvertently be added as persistent.
+
+ .. change::
+ :tags: orm
+ :tickets: 1314
+
+ Added "post_configure_attribute" method to InstrumentationManager,
+ so that the "listen_for_events.py" example works again.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ a forward and complementing backwards reference which are both
+ of the same direction, i.e. ONETOMANY or MANYTOONE,
+ is now detected, and an error message is raised.
+ Saves crazy CircularDependencyErrors later on.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Fixed bugs in Query regarding simultaneous selection of
+ multiple joined-table inheritance entities with common base
+ classes:
+
+ - previously the adaption applied to "B" on
+ "A JOIN B" would be erroneously partially applied
+ to "A".
+
+ - comparisons on relations (i.e. A.related==someb)
+ were not getting adapted when they should.
+
+ - Other filterings, like
+ query(A).join(A.bs).filter(B.foo=='bar'), were erroneously
+ adapting "B.foo" as though it were an "A".
+
+ .. change::
+ :tags: orm
+ :tickets: 1325
+
+ Fixed adaptation of EXISTS clauses via any(), has(), etc.
+ in conjunction with an aliased object on the left and
+ of_type() on the right.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Added an attribute helper method ``set_committed_value`` in
+ sqlalchemy.orm.attributes. Given an object, attribute name,
+ and value, will set the value on the object as part of its
+ "committed" state, i.e. state that is understood to have
+ been loaded from the database. Helps with the creation of
+ homegrown collection loaders and such.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Query won't fail with weakref error when a non-mapper/class
+ instrumented descriptor is passed, raises
+ "Invalid column expession".
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Query.group_by() properly takes into account aliasing applied
+ to the FROM clause, such as with select_from(), using
+ with_polymorphic(), or using from_self().
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ An alias() of a select() will convert to a "scalar subquery"
+ when used in an unambiguously scalar context, i.e. it's used
+ in a comparison operation. This applies to
+ the ORM when using query.subquery() as well.
+
+ .. change::
+ :tags: sql
+ :tickets: 1302
+
+ Fixed missing _label attribute on Function object, others
+ when used in a select() with use_labels (such as when used
+ in an ORM column_property()).
+
+ .. change::
+ :tags: sql
+ :tickets: 1309
+
+ anonymous alias names now truncate down to the max length
+ allowed by the dialect. More significant on DBs like
+ Oracle with very small character limits.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ the __selectable__() interface has been replaced entirely
+ by __clause_element__().
+
+ .. change::
+ :tags: sql
+ :tickets: 1299
+
+ The per-dialect cache used by TypeEngine to cache
+ dialect-specific types is now a WeakKeyDictionary.
+ This to prevent dialect objects from
+ being referenced forever for an application that
+ creates an arbitrarily large number of engines
+ or dialects. There is a small performance penalty
+ which will be resolved in 0.6.
+
+ .. change::
+ :tags: sqlite
+ :tickets:
+
+ Fixed SQLite reflection methods so that non-present
+ cursor.description, which triggers an auto-cursor
+ close, will be detected so that no results doesn't
+ fail on recent versions of pysqlite which raise
+ an error when fetchone() called with no rows present.
+
+ .. change::
+ :tags: postgresql
+ :tickets:
+
+ Index reflection won't fail when an index with
+ multiple expressions is encountered.
+
+ .. change::
+ :tags: postgresql
+ :tickets: 1327
+
+ Added PGUuid and PGBit types to
+ sqlalchemy.databases.postgres.
+
+ .. change::
+ :tags: postgresql
+ :tickets: 1327
+
+ Refection of unknown PG types won't crash when those
+ types are specified within a domain.
+
+ .. change::
+ :tags: mssql
+ :tickets:
+
+ Preliminary support for pymssql 1.0.1
+
+ .. change::
+ :tags: mssql
+ :tickets:
+
+ Corrected issue on mssql where max_identifier_length was
+ not being respected.
+
+ .. change::
+ :tags: extensions
+ :tickets:
+
+ Fixed a recursive pickling issue in serializer, triggered
+ by an EXISTS or other embedded FROM construct.
+
+ .. change::
+ :tags: extensions
+ :tickets:
+
+ Declarative locates the "inherits" class using a search
+ through __bases__, to skip over mixins that are local
+ to subclasses.
+
+ .. change::
+ :tags: extensions
+ :tickets:
+
+ Declarative figures out joined-table inheritance primary join
+ condition even if "inherits" mapper argument is given
+ explicitly.
+
+ .. change::
+ :tags: extensions
+ :tickets:
+
+ Declarative will properly interpret the "foreign_keys" argument
+ on a backref() if it's a string.
+
+ .. change::
+ :tags: extensions
+ :tickets:
+
+ Declarative will accept a table-bound column as a property
+ when used in conjunction with __table__, if the column is already
+ present in __table__. The column will be remapped to the given
+ key the same way as when added to the mapper() properties dict.
+
+.. changelog::
+ :version: 0.5.2
+ :released: Sat Jan 24 2009
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Further refined 0.5.1's warning about delete-orphan cascade
+ placed on a many-to-many relation. First, the bad news:
+ the warning will apply to both many-to-many as well as
+ many-to-one relations. This is necessary since in both
+ cases, SQLA does not scan the full set of potential parents
+ when determining "orphan" status - for a persistent object
+ it only detects an in-python de-association event to establish
+ the object as an "orphan". Next, the good news: to support
+ one-to-one via a foreign key or assocation table, or to
+ support one-to-many via an association table, a new flag
+ single_parent=True may be set which indicates objects
+ linked to the relation are only meant to have a single parent.
+ The relation will raise an error if multiple parent-association
+ events occur within Python.
+
+ .. change::
+ :tags: orm
+ :tickets: 1292
+
+ Adjusted the attribute instrumentation change from 0.5.1 to
+ fully establish instrumentation for subclasses where the mapper
+ was created after the superclass had already been fully
+ instrumented.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Fixed bug in delete-orphan cascade whereby two one-to-one
+ relations from two different parent classes to the same target
+ class would prematurely expunge the instance.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Fixed an eager loading bug whereby self-referential eager
+ loading would prevent other eager loads, self referential or not,
+ from joining to the parent JOIN properly. Thanks to Alex K
+ for creating a great test case.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ session.expire() and related methods will not expire() unloaded
+ deferred attributes. This prevents them from being needlessly
+ loaded when the instance is refreshed.
+
+ .. change::
+ :tags: orm
+ :tickets: 1293
+
+ query.join()/outerjoin() will now properly join an aliased()
+ construct to the existing left side, even if query.from_self()
+ or query.select_from(someselectable) has been called.
+
+ .. change::
+ :tags: sql
+ :tickets: 1284
+
+ Further fixes to the "percent signs and spaces in column/table
+ names" functionality.
+
+ .. change::
+ :tags: mssql
+ :tickets: 1291
+
+ Restored convert_unicode handling. Results were being passed
+ on through without conversion.
+
+ .. change::
+ :tags: mssql
+ :tickets: 1282
+
+ Really fixing the decimal handling this time..
+
+ .. change::
+ :tags: Ticket:1289, mssql
+ :tickets:
+
+ Modified table reflection code to use only kwargs when
+ constructing tables.
+
+.. changelog::
+ :version: 0.5.1
+ :released: Sat Jan 17 2009
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Removed an internal join cache which could potentially leak
+ memory when issuing query.join() repeatedly to ad-hoc
+ selectables.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ The "clear()", "save()", "update()", "save_or_update()"
+ Session methods have been deprecated, replaced by
+ "expunge_all()" and "add()". "expunge_all()" has also
+ been added to ScopedSession.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Modernized the "no mapped table" exception and added a more
+ explicit __table__/__tablename__ exception to declarative.
+
+ .. change::
+ :tags: orm
+ :tickets: 1237
+
+ Concrete inheriting mappers now instrument attributes which
+ are inherited from the superclass, but are not defined for
+ the concrete mapper itself, with an InstrumentedAttribute that
+ issues a descriptive error when accessed.
+
+ .. change::
+ :tags: orm
+ :tickets: 1237, 781
+
+ Added a new `relation()` keyword `back_populates`. This
+ allows configuation of backreferences using explicit
+ relations. This is required when creating
+ bidirectional relations between a hierarchy of concrete
+ mappers and another class.
+
+ .. change::
+ :tags: orm
+ :tickets: 1237
+
+ Test coverage added for `relation()` objects specified on
+ concrete mappers.
+
+ .. change::
+ :tags: orm
+ :tickets: 1276
+
+ Query.from_self() as well as query.subquery() both disable
+ the rendering of eager joins inside the subquery produced.
+ The "disable all eager joins" feature is available publically
+ via a new query.enable_eagerloads() generative.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Added a rudimental series of set operations to Query that
+ receive Query objects as arguments, including union(),
+ union_all(), intersect(), except_(), insertsect_all(),
+ except_all(). See the API documentation for
+ Query.union() for examples.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Fixed bug that prevented Query.join() and eagerloads from
+ attaching to a query that selected from a union or aliased union.
+
+ .. change::
+ :tags: orm
+ :tickets: 1237
+
+ A short documentation example added for bidirectional
+ relations specified on concrete mappers.
+
+ .. change::
+ :tags: orm
+ :tickets: 1269
+
+ Mappers now instrument class attributes upon construction
+ with the final InstrumentedAttribute object which remains
+ persistent. The `_CompileOnAttr`/`__getattribute__()`
+ methodology has been removed. The net effect is that
+ Column-based mapped class attributes can now be used fully
+ at the class level without invoking a mapper compilation
+ operation, greatly simplifying typical usage patterns
+ within declarative.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ ColumnProperty (and front-end helpers such as ``deferred``) no
+ longer ignores unknown **keyword arguments.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Fixed a bug with the unitofwork's "row switch" mechanism,
+ i.e. the conversion of INSERT/DELETE into an UPDATE, when
+ combined with joined-table inheritance and an object
+ which contained no defined values for the child table where
+ an UPDATE with no SET clause would be rendered.
+
+ .. change::
+ :tags: orm
+ :tickets: 1281
+
+ Using delete-orphan on a many-to-many relation is deprecated.
+ This produces misleading or erroneous results since SQLA does
+ not retrieve the full list of "parents" for m2m. To get delete-orphan
+ behavior with an m2m table, use an explcit association class
+ so that the individual association row is treated as a parent.
+
+ .. change::
+ :tags: orm
+ :tickets: 1281
+
+ delete-orphan cascade always requires delete cascade. Specifying
+ delete-orphan without delete now raises a deprecation warning.
+
+ .. change::
+ :tags: sql
+ :tickets: 1256
+
+ Improved the methodology to handling percent signs in column
+ names from. Added more tests. MySQL and
+ PostgreSQL dialects still do not issue correct CREATE TABLE
+ statements for identifiers with percent signs in them.
+
+ .. change::
+ :tags: schema
+ :tickets: 1214
+
+ Index now accepts column-oriented InstrumentedAttributes
+ (i.e. column-based mapped class attributes) as column
+ arguments.
+
+ .. change::
+ :tags: schema
+ :tickets:
+
+ Column with no name (as in declarative) won't raise a
+ NoneType error when it's string output is requsted
+ (such as in a stack trace).
+
+ .. change::
+ :tags: schema
+ :tickets: 1278
+
+ Fixed bug when overriding a Column with a ForeignKey
+ on a reflected table, where derived columns (i.e. the
+ "virtual" columns of a select, etc.) would inadvertently
+ call upon schema-level cleanup logic intended only
+ for the original column.
+
+ .. change::
+ :tags: declarative
+ :tickets:
+
+ Can now specify Column objects on subclasses which have no
+ table of their own (i.e. use single table inheritance).
+ The columns will be appended to the base table, but only
+ mapped by the subclass.
+
+ .. change::
+ :tags: declarative
+ :tickets:
+
+ For both joined and single inheriting subclasses, the subclass
+ will only map those columns which are already mapped on the
+ superclass and those explicit on the subclass. Other
+ columns that are present on the `Table` will be excluded
+ from the mapping by default, which can be disabled
+ by passing a blank `exclude_properties` collection to the
+ `__mapper_args__`. This is so that single-inheriting
+ classes which define their own columns are the only classes
+ to map those columns. The effect is actually a more organized
+ mapping than you'd normally get with explicit `mapper()`
+ calls unless you set up the `exclude_properties` arguments
+ explicitly.
+
+ .. change::
+ :tags: declarative
+ :tickets:
+
+ It's an error to add new Column objects to a declarative class
+ that specified an existing table using __table__.
+
+ .. change::
+ :tags: mysql
+ :tickets:
+
+ Added the missing keywords from MySQL 4.1 so they get escaped
+ properly.
+
+ .. change::
+ :tags: mssql
+ :tickets: 1280
+
+ Corrected handling of large decimal values with more robust
+ tests. Removed string manipulation on floats.
+
+ .. change::
+ :tags: mssql
+ :tickets:
+
+ Modified the do_begin handling in mssql to use the Cursor not
+ the Connection so it is DBAPI compatible.
+
+ .. change::
+ :tags: mssql
+ :tickets:
+
+ Corrected SAVEPOINT support on adodbapi by changing the
+ handling of savepoint_release, which is unsupported on mssql.
+
+.. changelog::
+ :version: 0.5.0
+ :released: Tue Jan 06 2009
+
+ .. change::
+ :tags: general
+ :tickets:
+
+ Documentation has been converted to Sphinx. In particular,
+ the generated API documentation has been constructed into a
+ full blown "API Reference" section which organizes editorial
+ documentation combined with generated docstrings. Cross
+ linking between sections and API docs are vastly improved, a
+ javascript-powered search feature is provided, and a full
+ index of all classes, functions and members is provided.
+
+ .. change::
+ :tags: general
+ :tickets:
+
+ setup.py now imports setuptools only optionally. If not
+ present, distutils is used. The new "pip" installer is
+ recommended over easy_install as it installs in a more
+ simplified way.
+
+ .. change::
+ :tags: general
+ :tickets:
+
+ added an extremely basic illustration of a PostGIS integration
+ to the examples folder.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Query.with_polymorphic() now accepts a third argument
+ "discriminator" which will replace the value of
+ mapper.polymorphic_on for that query. Mappers themselves no
+ longer require polymorphic_on to be set, even if the mapper
+ has a polymorphic_identity. When not set, the mapper will
+ load non-polymorphically by default. Together, these two
+ features allow a non-polymorphic concrete inheritance setup to
+ use polymorphic loading on a per-query basis, since concrete
+ setups are prone to many issues when used polymorphically in
+ all cases.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ dynamic_loader accepts a query_class= to customize the Query
+ classes used for both the dynamic collection and the queries
+ built from it.
+
+ .. change::
+ :tags: orm
+ :tickets: 1079
+
+ query.order_by() accepts None which will remove any pending
+ order_by state from the query, as well as cancel out any
+ mapper/relation configured ordering. This is primarily useful
+ for overriding the ordering specified on a dynamic_loader().
+
+ .. change::
+ :tags: sql
+ :tickets: 935
+
+ RowProxy objects can be used in place of dictionary arguments
+ sent to connection.execute() and friends.
+
+ .. change::
+ :tags: dialect
+ :tickets:
+
+ Added a new description_encoding attribute on the dialect that
+ is used for encoding the column name when processing the
+ metadata. This usually defaults to utf-8.
+
+ .. change::
+ :tags: mssql
+ :tickets:
+
+ Added in a new MSGenericBinary type. This maps to the Binary
+ type so it can implement the specialized behavior of treating
+ length specified types as fixed-width Binary types and
+ non-length types as an unbound variable length Binary type.
+
+ .. change::
+ :tags: mssql
+ :tickets: 1249
+
+ Added in new types: MSVarBinary and MSImage.
+
+ .. change::
+ :tags: mssql
+ :tickets:
+
+ Added in the MSReal, MSNText, MSSmallDateTime, MSTime,
+ MSDateTimeOffset, and MSDateTime2 types
+
+ .. change::
+ :tags: sqlite
+ :tickets: 1266
+
+ Table reflection now stores the actual DefaultClause value for
+ the column.
+
+ .. change::
+ :tags: sqlite
+ :tickets:
+
+ bugfixes, behavioral changes
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Exceptions raised during compile_mappers() are now preserved
+ to provide "sticky behavior" - if a hasattr() call on a
+ pre-compiled mapped attribute triggers a failing compile and
+ suppresses the exception, subsequent compilation is blocked
+ and the exception will be reiterated on the next compile()
+ call. This issue occurs frequently when using declarative.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ property.of_type() is now recognized on a single-table
+ inheriting target, when used in the context of
+ prop.of_type(..).any()/has(), as well as
+ query.join(prop.of_type(...)).
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ query.join() raises an error when the target of the join
+ doesn't match the property-based attribute - while it's
+ unlikely anyone is doing this, the SQLAlchemy author was
+ guilty of this particular loosey-goosey behavior.
+
+ .. change::
+ :tags: orm
+ :tickets: 1272
+
+ Fixed bug when using weak_instance_map=False where modified
+ events would not be intercepted for a flush().
+
+ .. change::
+ :tags: orm
+ :tickets: 1268
+
+ Fixed some deep "column correspondence" issues which could
+ impact a Query made against a selectable containing multiple
+ versions of the same table, as well as unions and similar
+ which contained the same table columns in different column
+ positions at different levels.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Custom comparator classes used in conjunction with
+ column_property(), relation() etc. can define new comparison
+ methods on the Comparator, which will become available via
+ __getattr__() on the InstrumentedAttribute. In the case of
+ synonym() or comparable_property(), attributes are resolved
+ first on the user-defined descriptor, then on the user-defined
+ comparator.
+
+ .. change::
+ :tags: orm
+ :tickets: 976
+
+ Added ScopedSession.is_active accessor.
+
+ .. change::
+ :tags: orm
+ :tickets: 1262
+
+ Can pass mapped attributes and column objects as keys to
+ query.update({}).
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Mapped attributes passed to the values() of an expression
+ level insert() or update() will use the keys of the mapped
+ columns, not that of the mapped attribute.
+
+ .. change::
+ :tags: orm
+ :tickets: 1242
+
+ Corrected problem with Query.delete() and Query.update() not
+ working properly with bind parameters.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Query.select_from(), from_statement() ensure that the given
+ argument is a FromClause, or Text/Select/Union, respectively.
+
+ .. change::
+ :tags: orm
+ :tickets: 1253
+
+ Query() can be passed a "composite" attribute as a column
+ expression and it will be expanded. Somewhat related to.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Query() is a little more robust when passed various column
+ expressions such as strings, clauselists, text() constructs
+ (which may mean it just raises an error more nicely).
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ first() works as expected with Query.from_statement().
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Fixed bug introduced in 0.5rc4 involving eager loading not
+ functioning for properties which were added to a mapper
+ post-compile using add_property() or equivalent.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Fixed bug where many-to-many relation() with viewonly=True
+ would not correctly reference the link between
+ secondary->remote.
+
+ .. change::
+ :tags: orm
+ :tickets: 1232
+
+ Duplicate items in a list-based collection will be maintained
+ when issuing INSERTs to a "secondary" table in a many-to-many
+ relation. Assuming the m2m table has a unique or primary key
+ constraint on it, this will raise the expected constraint
+ violation instead of silently dropping the duplicate
+ entries. Note that the old behavior remains for a one-to-many
+ relation since collection entries in that case don't result in
+ INSERT statements and SQLA doesn't manually police
+ collections.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Query.add_column() can accept FromClause objects in the same
+ manner as session.query() can.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Comparison of many-to-one relation to NULL is properly
+ converted to IS NOT NULL based on not_().
+
+ .. change::
+ :tags: orm
+ :tickets: 1087
+
+ Extra checks added to ensure explicit
+ primaryjoin/secondaryjoin are ClauseElement instances, to
+ prevent more confusing errors later on.
+
+ .. change::
+ :tags: orm
+ :tickets: 1236
+
+ Improved mapper() check for non-class classes.
+
+ .. change::
+ :tags: orm
+ :tickets: 5051
+
+ comparator_factory argument is now documented and supported by
+ all MapperProperty types, including column_property(),
+ relation(), backref(), and synonym().
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Changed the name of PropertyLoader to RelationProperty, to be
+ consistent with all the other names. PropertyLoader is still
+ present as a synonym.
+
+ .. change::
+ :tags: orm
+ :tickets: 1099, 1228
+
+ fixed "double iter()" call causing bus errors in shard API,
+ removed errant result.close() left over from the 0.4
+ version.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ made Session.merge cascades not trigger autoflush. Fixes
+ merged instances getting prematurely inserted with missing
+ values.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Two fixes to help prevent out-of-band columns from being
+ rendered in polymorphic_union inheritance scenarios (which
+ then causes extra tables to be rendered in the FROM clause
+ causing cartesian products):
+
+ - improvements to "column adaption" for a->b->c inheritance
+ situations to better locate columns that are related to
+ one another via multiple levels of indirection, rather
+ than rendering the non-adapted column.
+
+ - the "polymorphic discriminator" column is only rendered
+ for the actual mapper being queried against. The column
+ won't be "pulled in" from a subclass or superclass mapper
+ since it's not needed.
+
+ .. change::
+ :tags: orm
+ :tickets: 1072
+
+ Fixed shard_id argument on ShardedSession.execute().
+
+ .. change::
+ :tags: sql
+ :tickets: 1256
+
+ Columns can again contain percent signs within their
+ names.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ sqlalchemy.sql.expression.Function is now a public class. It
+ can be subclassed to provide user-defined SQL functions in an
+ imperative style, including with pre-established behaviors.
+ The postgis.py example illustrates one usage of this.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ PickleType now favors == comparison by default, if the
+ incoming object (such as a dict) implements __eq__(). If the
+ object does not implement __eq__() and mutable=True, a
+ deprecation warning is raised.
+
+ .. change::
+ :tags: sql
+ :tickets: 1215
+
+ Fixed the import weirdness in sqlalchemy.sql to not export
+ __names__.
+
+ .. change::
+ :tags: sql
+ :tickets: 1238
+
+ Using the same ForeignKey object repeatedly raises an error
+ instead of silently failing later.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Added NotImplementedError for params() method on
+ Insert/Update/Delete constructs. These items currently don't
+ support this functionality, which also would be a little
+ misleading compared to values().
+
+ .. change::
+ :tags: sql
+ :tickets: 650
+
+ Reflected foreign keys will properly locate their referenced
+ column, even if the column was given a "key" attribute
+ different from the reflected name. This is achieved via a new
+ flag on ForeignKey/ForeignKeyConstraint called "link_to_name",
+ if True means the given name is the referred-to column's name,
+ not its assigned key.
+
+ .. change::
+ :tags: sql
+ :tickets: 1253
+
+ select() can accept a ClauseList as a column in the same way
+ as a Table or other selectable and the interior expressions
+ will be used as column elements.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ the "passive" flag on session.is_modified() is correctly
+ propagated to the attribute manager.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ union() and union_all() will not whack any order_by() that has
+ been applied to the select()s inside. If you union() a
+ select() with order_by() (presumably to support LIMIT/OFFSET),
+ you should also call self_group() on it to apply parenthesis.
+
+ .. change::
+ :tags: engine/pool
+ :tickets: 1246
+
+ Connection.invalidate() checks for closed status to avoid
+ attribute errors.
+
+ .. change::
+ :tags: engine/pool
+ :tickets: 1094
+
+ NullPool supports reconnect on failure behavior.
+
+ .. change::
+ :tags: engine/pool
+ :tickets: 799
+
+ Added a mutex for the initial pool creation when using
+ pool.manage(dbapi). This prevents a minor case of "dogpile"
+ behavior which would otherwise occur upon a heavy load
+ startup.
+
+ .. change::
+ :tags: engine/pool
+ :tickets:
+
+ _execute_clauseelement() goes back to being a private method.
+ Subclassing Connection is not needed now that ConnectionProxy
+ is available.
+
+ .. change::
+ :tags: documentation
+ :tickets: 1149, 1200
+
+ Tickets.
+
+ .. change::
+ :tags: documentation
+ :tickets:
+
+ Added note about create_session() defaults.
+
+ .. change::
+ :tags: documentation
+ :tickets:
+
+ Added section about metadata.reflect().
+
+ .. change::
+ :tags: documentation
+ :tickets:
+
+ Updated `TypeDecorator` section.
+
+ .. change::
+ :tags: documentation
+ :tickets:
+
+ Rewrote the "threadlocal" strategy section of the docs due to
+ recent confusion over this feature.
+
+ .. change::
+ :tags: documentation
+ :tickets:
+
+ Removed badly out of date 'polymorphic_fetch' and
+ 'select_table' docs from inheritance, reworked the second half
+ of "joined table inheritance".
+
+ .. change::
+ :tags: documentation
+ :tickets:
+
+ Documented `comparator_factory` kwarg, added new doc section
+ "Custom Comparators".
+
+ .. change::
+ :tags: mssql
+ :tickets: 1254
+
+ Refactored the Date/Time types. The ``smalldatetime`` data
+ type no longer truncates to a date only, and will now be
+ mapped to the MSSmallDateTime type.
+
+ .. change::
+ :tags: mssql
+ :tickets:
+
+ Corrected an issue with Numerics to accept an int.
+
+ .. change::
+ :tags: mssql
+ :tickets:
+
+ Mapped ``char_length`` to the ``LEN()`` function.
+
+ .. change::
+ :tags: mssql
+ :tickets:
+
+ If an ``INSERT`` includes a subselect the ``INSERT`` is
+ converted from an ``INSERT INTO VALUES`` construct to a
+ ``INSERT INTO SELECT`` construct.
+
+ .. change::
+ :tags: mssql
+ :tickets:
+
+ If the column is part of a ``primary_key`` it will be ``NOT
+ NULL`` since MSSQL doesn't allow ``NULL`` in primary_key
+ columns.
+
+ .. change::
+ :tags: mssql
+ :tickets: 1249
+
+ ``MSBinary`` now returns a ``BINARY`` instead of an
+ ``IMAGE``. This is a backwards incompatible change in that
+ ``BINARY`` is a fixed length data type whereas ``IMAGE`` is a
+ variable length data type.
+
+ .. change::
+ :tags: mssql
+ :tickets: 1258
+
+ ``get_default_schema_name`` is now reflected from the database
+ based on the user's default schema. This only works with MSSQL
+ 2005 and later.
+
+ .. change::
+ :tags: mssql
+ :tickets: 1248
+
+ Added collation support through the use of a new collation
+ argument. This is supported on the following types: char,
+ nchar, varchar, nvarchar, text, ntext.
+
+ .. change::
+ :tags: mssql
+ :tickets:
+
+ Changes to the connection string parameters favor DSN as the
+ default specification for pyodbc. See the mssql.py docstring
+ for detailed usage instructions.
+
+ .. change::
+ :tags: mssql
+ :tickets:
+
+ Added experimental support of savepoints. It currently does
+ not work fully with sessions.
+
+ .. change::
+ :tags: mssql
+ :tickets: 1243
+
+ Support for three levels of column nullability: NULL, NOT
+ NULL, and the database's configured default. The default
+ Column configuration (nullable=True) will now generate NULL in
+ the DDL. Previously no specification was emitted and the
+ database default would take effect (usually NULL, but not
+ always). To explicitly request the database default,
+ configure columns with nullable=None and no specification will
+ be emitted in DDL. This is backwards incompatible
+ behavior.
+
+ .. change::
+ :tags: postgres
+ :tickets: 1267
+
+ "%" signs in text() constructs are automatically escaped to
+ "%%". Because of the backwards incompatible nature of this
+ change, a warning is emitted if '%%' is detected in the
+ string.
+
+ .. change::
+ :tags: postgres
+ :tickets:
+
+ Calling alias.execute() in conjunction with
+ server_side_cursors won't raise AttributeError.
+
+ .. change::
+ :tags: postgres
+ :tickets: 714
+
+ Added Index reflection support to PostgreSQL, using a great
+ patch we long neglected, submitted by Ken
+ Kuhlman.
+
+ .. change::
+ :tags: oracle
+ :tickets:
+
+ Adjusted the format of create_xid() to repair two-phase
+ commit. We now have field reports of Oracle two-phase commit
+ working properly with this change.
+
+ .. change::
+ :tags: oracle
+ :tickets: 1233
+
+ Added OracleNVarchar type, produces NVARCHAR2, and also
+ subclasses Unicode so that convert_unicode=True by default.
+ NVARCHAR2 reflects into this type automatically so these
+ columns pass unicode on a reflected table with no explicit
+ convert_unicode=True flags.
+
+ .. change::
+ :tags: oracle
+ :tickets: 1265
+
+ Fixed bug which was preventing out params of certain types
+ from being received; thanks a ton to huddlej at wwu.edu !
+
+ .. change::
+ :tags: mysql
+ :tickets:
+
+ "%" signs in text() constructs are automatically escaped to
+ "%%". Because of the backwards incompatible nature of this
+ change, a warning is emitted if '%%' is detected in the
+ string.
+
+ .. change::
+ :tags: mysql
+ :tickets: 1241
+
+ Fixed bug in exception raise when FK columns not present
+ during reflection.
+
+ .. change::
+ :tags: mysql
+ :tickets:
+
+ Fixed bug involving reflection of a remote-schema table with a
+ foreign key ref to another table in that schema.
+
+ .. change::
+ :tags: associationproxy
+ :tickets:
+
+ The association proxy properties are make themselves available
+ at the class level, e.g. MyClass.aproxy. Previously this
+ evaluated to None.
+
+ .. change::
+ :tags: declarative
+ :tickets:
+
+ The full list of arguments accepted as string by backref()
+ includes 'primaryjoin', 'secondaryjoin', 'secondary',
+ 'foreign_keys', 'remote_side', 'order_by'.
+
+.. changelog::
+ :version: 0.5.0rc4
+ :released: Fri Nov 14 2008
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Query.count() has been enhanced to do the "right thing" in a
+ wider variety of cases. It can now count multiple-entity
+ queries, as well as column-based queries. Note that this means
+ if you say query(A, B).count() without any joining criterion,
+ it's going to count the cartesian product of A*B. Any query
+ which is against column-based entities will automatically
+ issue "SELECT count(1) FROM (SELECT...)" so that the real
+ rowcount is returned, meaning a query such as
+ query(func.count(A.name)).count() will return a value of one,
+ since that query would return one row.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Lots of performance tuning. A rough guesstimate over various
+ ORM operations places it 10% faster over 0.5.0rc3, 25-30% over
+ 0.4.8.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ bugfixes and behavioral changes
+
+ .. change::
+ :tags: general
+ :tickets:
+
+ global "propigate"->"propagate" change.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Adjustments to the enhanced garbage collection on
+ InstanceState to better guard against errors due to lost
+ state.
+
+ .. change::
+ :tags: orm
+ :tickets: 1220
+
+ Query.get() returns a more informative error message when
+ executed against multiple entities.
+
+ .. change::
+ :tags: orm
+ :tickets: 1140, 1221
+
+ Restored NotImplementedError on Cls.relation.in_()
+
+ .. change::
+ :tags: orm
+ :tickets: 1226
+
+ Fixed PendingDeprecationWarning involving order_by parameter
+ on relation().
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Removed the 'properties' attribute of the Connection object,
+ Connection.info should be used.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Restored "active rowcount" fetch before ResultProxy autocloses
+ the cursor. This was removed in 0.5rc3.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Rearranged the `load_dialect_impl()` method in `TypeDecorator`
+ such that it will take effect even if the user-defined
+ `TypeDecorator` uses another `TypeDecorator` as its impl.
+
+ .. change::
+ :tags: access
+ :tickets:
+
+ Added support for Currency type.
+
+ .. change::
+ :tags: access
+ :tickets: 1017
+
+ Functions were not return their result.
+
+ .. change::
+ :tags: access
+ :tickets: 1017
+
+ Corrected problem with joins. Access only support LEFT OUTER
+ or INNER not just JOIN by itself.
+
+ .. change::
+ :tags: mssql
+ :tickets:
+
+ Lots of cleanup and fixes to correct problems with limit and
+ offset.
+
+ .. change::
+ :tags: mssql
+ :tickets:
+
+ Correct situation where subqueries as part of a binary
+ expression need to be translated to use the IN and NOT IN
+ syntax.
+
+ .. change::
+ :tags: mssql
+ :tickets: 1216
+
+ Fixed E Notation issue that prevented the ability to insert
+ decimal values less than 1E-6.
+
+ .. change::
+ :tags: mssql
+ :tickets: 1217
+
+ Corrected problems with reflection when dealing with schemas,
+ particularly when those schemas are the default
+ schema.
+
+ .. change::
+ :tags: mssql
+ :tickets:
+
+ Corrected problem with casting a zero length item to a
+ varchar. It now correctly adjusts the CAST.
+
+ .. change::
+ :tags: ext
+ :tickets:
+
+ Can now use a custom "inherit_condition" in __mapper_args__
+ when using declarative.
+
+ .. change::
+ :tags: ext
+ :tickets:
+
+ fixed string-based "remote_side", "order_by" and others not
+ propagating correctly when used in backref().
+
+.. changelog::
+ :version: 0.5.0rc3
+ :released: Fri Nov 07 2008
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Added two new hooks to SessionExtension: after_bulk_delete()
+ and after_bulk_update(). after_bulk_delete() is called after
+ a bulk delete() operation on a query. after_bulk_update() is
+ called after a bulk update() operation on a query.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ SQL compiler optimizations and complexity reduction. The call
+ count for compiling a typical select() construct is 20% less
+ versus 0.5.0rc2.
+
+ .. change::
+ :tags: sql
+ :tickets: 1211
+
+ Dialects can now generate label names of adjustable
+ length. Pass in the argument "label_length=<value>" to
+ create_engine() to adjust how many characters max will be
+ present in dynamically generated column labels, i.e.
+ "somecolumn AS somelabel". Any value less than 6 will result
+ in a label of minimal size, consisting of an underscore and a
+ numeric counter. The compiler uses the value of
+ dialect.max_identifier_length as a default.
+
+ .. change::
+ :tags: ext
+ :tickets:
+
+ Added a new extension sqlalchemy.ext.serializer. Provides
+ Serializer/Deserializer "classes" which mirror
+ Pickle/Unpickle, as well as dumps() and loads(). This
+ serializer implements an "external object" pickler which keeps
+ key context-sensitive objects, including engines, sessions,
+ metadata, Tables/Columns, and mappers, outside of the pickle
+ stream, and can later restore the pickle using any
+ engine/metadata/session provider. This is used not for
+ pickling regular object instances, which are pickleable
+ without any special logic, but for pickling expression objects
+ and full Query objects, such that all mapper/engine/session
+ dependencies can be restored at unpickle time.
+
+ .. change::
+ :tags: oracle
+ :tickets:
+
+ Wrote a docstring for Oracle dialect. Apparently that Ohloh
+ "few source code comments" label is starting to sting :).
+
+ .. change::
+ :tags: oracle
+ :tickets: 536
+
+ Removed FIRST_ROWS() optimize flag when using LIMIT/OFFSET,
+ can be reenabled with optimize_limits=True create_engine()
+ flag.
+
+ .. change::
+ :tags: oracle
+ :tickets:
+
+ bugfixes and behavioral changes
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ "not equals" comparisons of simple many-to-one relation to an
+ instance will not drop into an EXISTS clause and will compare
+ foreign key columns instead.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Removed not-really-working use cases of comparing a collection
+ to an iterable. Use contains() to test for collection
+ membership.
+
+ .. change::
+ :tags: orm
+ :tickets: 1171
+
+ Improved the behavior of aliased() objects such that they more
+ accurately adapt the expressions generated, which helps
+ particularly with self-referential comparisons.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Fixed bug involving primaryjoin/secondaryjoin conditions
+ constructed from class-bound attributes (as often occurs when
+ using declarative), which later would be inappropriately
+ aliased by Query, particularly with the various EXISTS based
+ comparators.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Fixed bug when using multiple query.join() with an
+ aliased-bound descriptor which would lose the left alias.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Improved weakref identity map memory management to no longer
+ require mutexing, resurrects garbage collected instance on a
+ lazy basis for an InstanceState with pending changes.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ InstanceState object now removes circular references to itself
+ upon disposal to keep it outside of cyclic garbage collection.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ relation() won't hide unrelated ForeignKey errors inside of
+ the "please specify primaryjoin" message when determining join
+ condition.
+
+ .. change::
+ :tags: orm
+ :tickets: 1218
+
+ Fixed bug in Query involving order_by() in conjunction with
+ multiple aliases of the same class (will add tests in)
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ When using Query.join() with an explicit clause for the ON
+ clause, the clause will be aliased in terms of the left side
+ of the join, allowing scenarios like query(Source).
+ from_self().join((Dest, Source.id==Dest.source_id)) to work
+ properly.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ polymorphic_union() function respects the "key" of each Column
+ if they differ from the column's name.
+
+ .. change::
+ :tags: orm
+ :tickets: 1183
+
+ Repaired support for "passive-deletes" on a many-to-one
+ relation() with "delete" cascade.
+
+ .. change::
+ :tags: orm
+ :tickets: 1213
+
+ Fixed bug in composite types which prevented a primary-key
+ composite type from being mutated.
+
+ .. change::
+ :tags: orm
+ :tickets: 1202
+
+ Added more granularity to internal attribute access, such that
+ cascade and flush operations will not initialize unloaded
+ attributes and collections, leaving them intact for a
+ lazy-load later on. Backref events still initialize attrbutes
+ and collections for pending instances.
+
+ .. change::
+ :tags: sql
+ :tickets: 1212
+
+ Simplified the check for ResultProxy "autoclose without
+ results" to be based solely on presence of
+ cursor.description. All the regexp-based guessing about
+ statements returning rows has been removed.
+
+ .. change::
+ :tags: sql
+ :tickets: 1194
+
+ Direct execution of a union() construct will properly set up
+ result-row processing.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ The internal notion of an "OID" or "ROWID" column has been
+ removed. It's basically not used by any dialect, and the
+ possibility of its usage with psycopg2's cursor.lastrowid is
+ basically gone now that INSERT..RETURNING is available.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Removed "default_order_by()" method on all FromClause objects.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Repaired the table.tometadata() method so that a passed-in
+ schema argument is propagated to ForeignKey constructs.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Slightly changed behavior of IN operator for comparing to
+ empty collections. Now results in inequality comparison
+ against self. More portable, but breaks with stored procedures
+ that aren't pure functions.
+
+ .. change::
+ :tags: oracle
+ :tickets:
+
+ Setting the auto_convert_lobs to False on create_engine() will
+ also instruct the OracleBinary type to return the cx_oracle
+ LOB object unchanged.
+
+ .. change::
+ :tags: mysql
+ :tickets:
+
+ Fixed foreign key reflection in the edge case where a Table's
+ explicit schema= is the same as the schema (database) the
+ connection is attached to.
+
+ .. change::
+ :tags: mysql
+ :tickets:
+
+ No longer expects include_columns in table reflection to be
+ lower case.
+
+ .. change::
+ :tags: ext
+ :tickets: 1174
+
+ Fixed bug preventing declarative-bound "column" objects from
+ being used in column_mapped_collection().
+
+ .. change::
+ :tags: misc
+ :tickets: 1077
+
+ util.flatten_iterator() func doesn't interpret strings with
+ __iter__() methods as iterators, such as in pypy.
+
+.. changelog::
+ :version: 0.5.0rc2
+ :released: Sun Oct 12 2008
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Fixed bug involving read/write relation()s that contain
+ literal or other non-column expressions within their
+ primaryjoin condition equated to a foreign key column.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ "non-batch" mode in mapper(), a feature which allows mapper
+ extension methods to be called as each instance is
+ updated/inserted, now honors the insert order of the objects
+ given.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Fixed RLock-related bug in mapper which could deadlock upon
+ reentrant mapper compile() calls, something that occurs when
+ using declarative constructs inside of ForeignKey objects.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ ScopedSession.query_property now accepts a query_cls factory,
+ overriding the session's configured query_cls.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Fixed shared state bug interfering with ScopedSession.mapper's
+ ability to apply default __init__ implementations on object
+ subclasses.
+
+ .. change::
+ :tags: orm
+ :tickets: 1177
+
+ Fixed up slices on Query (i.e. query[x:y]) to work properly
+ for zero length slices, slices with None on either end.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Added an example illustrating Celko's "nested sets" as a
+ SQLA mapping.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ contains_eager() with an alias argument works even when
+ the alias is embedded in a SELECT, as when sent to the
+ Query via query.select_from().
+
+ .. change::
+ :tags: orm
+ :tickets: 1180
+
+ contains_eager() usage is now compatible with a Query that
+ also contains a regular eager load and limit/offset, in that
+ the columns are added to the Query-generated subquery.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ session.execute() will execute a Sequence object passed to
+ it (regression from 0.4).
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Removed the "raiseerror" keyword argument from object_mapper()
+ and class_mapper(). These functions raise in all cases
+ if the given class/instance is not mapped.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Fixed session.transaction.commit() on a autocommit=False
+ session not starting a new transaction.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Some adjustments to Session.identity_map's weak referencing
+ behavior to reduce asynchronous GC side effects.
+
+ .. change::
+ :tags: orm
+ :tickets: 1182
+
+ Adjustment to Session's post-flush accounting of newly
+ "clean" objects to better protect against operating on
+ objects as they're asynchronously gc'ed.
+
+ .. change::
+ :tags: sql
+ :tickets: 1074
+
+ column.in_(someselect) can now be used as a columns-clause
+ expression without the subquery bleeding into the FROM clause
+
+ .. change::
+ :tags: sqlite
+ :tickets: 968
+
+ Overhauled SQLite date/time bind/result processing to use
+ regular expressions and format strings, rather than
+ strptime/strftime, to generically support pre-1900 dates,
+ dates with microseconds.
+
+ .. change::
+ :tags: sqlite
+ :tickets:
+
+ String's (and Unicode's, UnicodeText's, etc.) convert_unicode
+ logic disabled in the sqlite dialect, to adjust for pysqlite
+ 2.5.0's new requirement that only Python unicode objects are
+ accepted;
+ http://itsystementwicklung.de/pipermail/list-pysqlite/2008-March/000018.html
+
+ .. change::
+ :tags: mysql
+ :tickets:
+
+ Temporary tables are now reflectable.
+
+ .. change::
+ :tags: oracle
+ :tickets: 1187
+
+ Oracle will detect string-based statements which contain
+ comments at the front before a SELECT as SELECT statements.
+
+.. changelog::
+ :version: 0.5.0rc1
+ :released: Thu Sep 11 2008
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Query now has delete() and update(values) methods. This allows
+ to perform bulk deletes/updates with the Query object.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ The RowTuple object returned by Query(*cols) now features
+ keynames which prefer mapped attribute names over column keys,
+ column keys over column names, i.e. Query(Class.foo,
+ Class.bar) will have names "foo" and "bar" even if those are
+ not the names of the underlying Column objects. Direct Column
+ objects such as Query(table.c.col) will return the "key"
+ attribute of the Column.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Added scalar() and value() methods to Query, each return a
+ single scalar value. scalar() takes no arguments and is
+ roughly equivalent to first()[0], value()
+ takes a single column expression and is roughly equivalent to
+ values(expr).next()[0].
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Improved the determination of the FROM clause when placing SQL
+ expressions in the query() list of entities. In particular
+ scalar subqueries should not "leak" their inner FROM objects
+ out into the enclosing query.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Joins along a relation() from a mapped class to a mapped
+ subclass, where the mapped subclass is configured with single
+ table inheritance, will include an IN clause which limits the
+ subtypes of the joined class to those requested, within the ON
+ clause of the join. This takes effect for eager load joins as
+ well as query.join(). Note that in some scenarios the IN
+ clause will appear in the WHERE clause of the query as well
+ since this discrimination has multiple trigger points.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ AttributeExtension has been refined such that the event
+ is fired before the mutation actually occurs. Additionally,
+ the append() and set() methods must now return the given value,
+ which is used as the value to be used in the mutation operation.
+ This allows creation of validating AttributeListeners which
+ raise before the action actually occurs, and which can change
+ the given value into something else before its used.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ column_property(), composite_property(), and relation() now
+ accept a single or list of AttributeExtensions using the
+ "extension" keyword argument.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ query.order_by().get() silently drops the "ORDER BY" from
+ the query issued by GET but does not raise an exception.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Added a Validator AttributeExtension, as well as a
+ @validates decorator which is used in a similar fashion
+ as @reconstructor, and marks a method as validating
+ one or more mapped attributes.
+
+ .. change::
+ :tags: orm
+ :tickets: 1140
+
+ class.someprop.in_() raises NotImplementedError pending the
+ implementation of "in_" for relation
+
+ .. change::
+ :tags: orm
+ :tickets: 1127
+
+ Fixed primary key update for many-to-many collections where
+ the collection had not been loaded yet
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Fixed bug whereby deferred() columns with a group in conjunction
+ with an otherwise unrelated synonym() would produce
+ an AttributeError during deferred load.
+
+ .. change::
+ :tags: orm
+ :tickets: 1128
+
+ The before_flush() hook on SessionExtension takes place before
+ the list of new/dirty/deleted is calculated for the final
+ time, allowing routines within before_flush() to further
+ change the state of the Session before the flush proceeds.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ The "extension" argument to Session and others can now
+ optionally be a list, supporting events sent to multiple
+ SessionExtension instances. Session places SessionExtensions
+ in Session.extensions.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Reentrant calls to flush() raise an error. This also serves
+ as a rudimentary, but not foolproof, check against concurrent
+ calls to Session.flush().
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Improved the behavior of query.join() when joining to
+ joined-table inheritance subclasses, using explicit join
+ criteria (i.e. not on a relation).
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ @orm.attributes.reconstitute and
+ MapperExtension.reconstitute have been renamed to
+ @orm.reconstructor and MapperExtension.reconstruct_instance
+
+ .. change::
+ :tags: orm
+ :tickets: 1129
+
+ Fixed @reconstructor hook for subclasses which inherit from a
+ base class.
+
+ .. change::
+ :tags: orm
+ :tickets: 1132
+
+ The composite() property type now supports a
+ __set_composite_values__() method on the composite class which
+ is required if the class represents state using attribute
+ names other than the column's keynames; default-generated
+ values now get populated properly upon flush. Also,
+ composites with attributes set to None compare correctly.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ The 3-tuple of iterables returned by attributes.get_history()
+ may now be a mix of lists and tuples. (Previously members
+ were always lists.)
+
+ .. change::
+ :tags: orm
+ :tickets: 1151
+
+ Fixed bug whereby changing a primary key attribute on an
+ entity where the attribute's previous value had been expired
+ would produce an error upon flush().
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Fixed custom instrumentation bug whereby get_instance_dict()
+ was not called for newly constructed instances not loaded
+ by the ORM.
+
+ .. change::
+ :tags: orm
+ :tickets: 1150
+
+ Session.delete() adds the given object to the session if
+ not already present. This was a regression bug from 0.4.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ The `echo_uow` flag on `Session` is deprecated, and unit-of-work
+ logging is now application-level only, not per-session level.
+
+ .. change::
+ :tags: orm
+ :tickets: 1153
+
+ Removed conflicting `contains()` operator from
+ `InstrumentedAttribute` which didn't accept `escape` kwaarg.
+
+ .. change::
+ :tags: declarative
+ :tickets: 1161
+
+ Fixed bug whereby mapper couldn't initialize if a composite
+ primary key referenced another table that was not defined
+ yet.
+
+ .. change::
+ :tags: declarative
+ :tickets:
+
+ Fixed exception throw which would occur when string-based
+ primaryjoin condition was used in conjunction with backref.
+
+ .. change::
+ :tags: schema
+ :tickets: 1033
+
+ Added "sorted_tables" accessor to MetaData, which returns
+ Table objects sorted in order of dependency as a list.
+ This deprecates the MetaData.table_iterator() method.
+ The "reverse=False" keyword argument has also been
+ removed from util.sort_tables(); use the Python
+ 'reversed' function to reverse the results.
+
+ .. change::
+ :tags: schema
+ :tickets:
+
+ The 'length' argument to all Numeric types has been renamed
+ to 'scale'. 'length' is deprecated and is still accepted
+ with a warning.
+
+ .. change::
+ :tags: schema
+ :tickets:
+
+ Dropped 0.3-compatibility for user defined types
+ (convert_result_value, convert_bind_param).
+
+ .. change::
+ :tags: sql
+ :tickets: 1068
+
+ Temporarily rolled back the "ORDER BY" enhancement from. This feature is on hold pending further
+ development.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ The exists() construct won't "export" its contained list
+ of elements as FROM clauses, allowing them to be used more
+ effectively in the columns clause of a SELECT.
+
+ .. change::
+ :tags: sql
+ :tickets: 798
+
+ and_() and or_() now generate a ColumnElement, allowing
+ boolean expressions as result columns, i.e.
+ select([and_(1, 0)]).
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Bind params now subclass ColumnElement which allows them to be
+ selectable by orm.query (they already had most ColumnElement
+ semantics).
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Added select_from() method to exists() construct, which becomes
+ more and more compatible with a regular select().
+
+ .. change::
+ :tags: sql
+ :tickets: 1160
+
+ Added func.min(), func.max(), func.sum() as "generic functions",
+ which basically allows for their return type to be determined
+ automatically. Helps with dates on SQLite, decimal types,
+ others.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ added decimal.Decimal as an "auto-detect" type; bind parameters
+ and generic functions will set their type to Numeric when a
+ Decimal is used.
+
+ .. change::
+ :tags: mysql
+ :tickets:
+
+ The 'length' argument to MSInteger, MSBigInteger, MSTinyInteger,
+ MSSmallInteger and MSYear has been renamed to 'display_width'.
+
+ .. change::
+ :tags: mysql
+ :tickets: 1146
+
+ Added MSMediumInteger type.
+
+ .. change::
+ :tags: mysql
+ :tickets:
+
+ the function func.utc_timestamp() compiles to UTC_TIMESTAMP, without
+ the parenthesis, which seem to get in the way when using in
+ conjunction with executemany().
+
+ .. change::
+ :tags: oracle
+ :tickets: 536
+
+ limit/offset no longer uses ROW NUMBER OVER to limit rows,
+ and instead uses subqueries in conjunction with a special
+ Oracle optimization comment. Allows LIMIT/OFFSET to work
+ in conjunction with DISTINCT.
+
+ .. change::
+ :tags: oracle
+ :tickets: 1155
+
+ has_sequence() now takes the current "schema" argument into
+ account
+
+ .. change::
+ :tags: oracle
+ :tickets: 1121
+
+ added BFILE to reflected type names
+
+.. changelog::
+ :version: 0.5beta3
+ :released: Mon Aug 04 2008
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ The "entity_name" feature of SQLAlchemy mappers has been
+ removed. For rationale, see http://tinyurl.com/6nm2ne
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ the "autoexpire" flag on Session, sessionmaker(), and
+ scoped_session() has been renamed to "expire_on_commit". It
+ does not affect the expiration behavior of rollback().
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ fixed endless loop bug which could occur within a mapper's
+ deferred load of inherited attributes.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ a legacy-support flag "_enable_transaction_accounting" flag
+ added to Session which when False, disables all
+ transaction-level object accounting, including expire on
+ rollback, expire on commit, new/deleted list maintenance, and
+ autoflush on begin.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ The 'cascade' parameter to relation() accepts None as a value,
+ which is equivalent to no cascades.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ A critical fix to dynamic relations allows the "modified"
+ history to be properly cleared after a flush().
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ user-defined @properties on a class are detected and left in
+ place during mapper initialization. This means that a
+ table-bound column of the same name will not be mapped at all
+ if a @property is in the way (and the column is not remapped
+ to a different name), nor will an instrumented attribute from
+ an inherited class be applied. The same rules apply for names
+ excluded using the include_properties/exclude_properties
+ collections.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Added a new SessionExtension hook called after_attach(). This
+ is called at the point of attachment for objects via add(),
+ add_all(), delete(), and merge().
+
+ .. change::
+ :tags: orm
+ :tickets: 1111
+
+ A mapper which inherits from another, when inheriting the
+ columns of its inherited mapper, will use any reassigned
+ property names specified in that inheriting mapper.
+ Previously, if "Base" had reassigned "base_id" to the name
+ "id", "SubBase(Base)" would still get an attribute called
+ "base_id". This could be worked around by explicitly stating
+ the column in each submapper as well but this is fairly
+ unworkable and also impossible when using declarative.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Fixed a series of potential race conditions in Session whereby
+ asynchronous GC could remove unmodified, no longer referenced
+ items from the session as they were present in a list of items
+ to be processed, typically during session.expunge_all() and
+ dependent methods.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Some improvements to the _CompileOnAttr mechanism which should
+ reduce the probability of "Attribute x was not replaced during
+ compile" warnings. (this generally applies to SQLA hackers,
+ like Elixir devs).
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Fixed bug whereby the "unsaved, pending instance" FlushError
+ raised for a pending orphan would not take superclass mappers
+ into account when generating the list of relations responsible
+ for the error.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ func.count() with no arguments renders as COUNT(*), equivalent
+ to func.count(text('*')).
+
+ .. change::
+ :tags: sql
+ :tickets: 1068
+
+ simple label names in ORDER BY expressions render as
+ themselves, and not as a re-statement of their corresponding
+ expression. This feature is currently enabled only for
+ SQLite, MySQL, and PostgreSQL. It can be enabled on other
+ dialects as each is shown to support this
+ behavior.
+
+ .. change::
+ :tags: ext
+ :tickets:
+
+ Class-bound attributes sent as arguments to relation()'s
+ remote_side and foreign_keys parameters are now accepted,
+ allowing them to be used with declarative. Additionally fixed
+ bugs involving order_by being specified as a class-bound
+ attribute in conjunction with eager loading.
+
+ .. change::
+ :tags: ext
+ :tickets:
+
+ declarative initialization of Columns adjusted so that
+ non-renamed columns initialize in the same way as a non
+ declarative mapper. This allows an inheriting mapper to set
+ up its same-named "id" columns in particular such that the
+ parent "id" column is favored over the child column, reducing
+ database round trips when this value is requested.
+
+ .. change::
+ :tags: mysql
+ :tickets: 1110
+
+ Quoting of MSEnum values for use in CREATE TABLE is now
+ optional & will be quoted on demand as required. (Quoting was
+ always optional for use with existing tables.)
+
+.. changelog::
+ :version: 0.5beta2
+ :released: Mon Jul 14 2008
+
+ .. change::
+ :tags: orm
+ :tickets: 870
+
+ In addition to expired attributes, deferred attributes also
+ load if their data is present in the result set.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ session.refresh() raises an informative error message if the
+ list of attributes does not include any column-based
+ attributes.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ query() raises an informative error message if no columns or
+ mappers are specified.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ lazy loaders now trigger autoflush before proceeding. This
+ allows expire() of a collection or scalar relation to function
+ properly in the context of autoflush.
+
+ .. change::
+ :tags: orm
+ :tickets: 887
+
+ column_property() attributes which represent SQL expressions
+ or columns that are not present in the mapped tables (such as
+ those from views) are automatically expired after an INSERT or
+ UPDATE, assuming they have not been locally modified, so that
+ they are refreshed with the most recent data upon access.
+
+ .. change::
+ :tags: orm
+ :tickets: 1082
+
+ Fixed explicit, self-referential joins between two
+ joined-table inheritance mappers when using query.join(cls,
+ aliased=True).
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Fixed query.join() when used in conjunction with a
+ columns-only clause and an SQL-expression ON clause in the
+ join.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ The "allow_column_override" flag from mapper() has been
+ removed. This flag is virtually always misunderstood. Its
+ specific functionality is available via the
+ include_properties/exclude_properties mapper arguments.
+
+ .. change::
+ :tags: orm
+ :tickets: 1066
+
+ Repaired `__str__()` method on Query.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Session.bind gets used as a default even when table/mapper
+ specific binds are defined.
+
+ .. change::
+ :tags: schema
+ :tickets: 1075
+
+ Added prefixes option to `Table` that accepts a list of
+ strings to insert after CREATE in the CREATE TABLE statement.
+
+ .. change::
+ :tags: schema
+ :tickets:
+
+ Unicode, UnicodeText types now set "assert_unicode" and
+ "convert_unicode" by default, but accept overriding
+ **kwargs for these values.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Added new match() operator that performs a full-text search.
+ Supported on PostgreSQL, SQLite, MySQL, MS-SQL, and Oracle
+ backends.
+
+ .. change::
+ :tags: sqlite
+ :tickets: 1090
+
+ Modified SQLite's representation of "microseconds" to match
+ the output of str(somedatetime), i.e. in that the microseconds
+ are represented as fractional seconds in string format. This
+ makes SQLA's SQLite date type compatible with datetimes that
+ were saved directly using Pysqlite (which just calls str()).
+ Note that this is incompatible with the existing microseconds
+ values in a SQLA 0.4 generated SQLite database file.
+
+ To get the old behavior globally:
+
+ from sqlalchemy.databases.sqlite import DateTimeMixin
+ DateTimeMixin.__legacy_microseconds__ = True
+
+ To get the behavior on individual DateTime types:
+
+ t = sqlite.SLDateTime()
+ t.__legacy_microseconds__ = True
+
+ Then use "t" as the type on the Column.
+
+ .. change::
+ :tags: sqlite
+ :tickets:
+
+ SQLite Date, DateTime, and Time types only accept Python
+ datetime objects now, not strings. If you'd like to format
+ dates as strings yourself with SQLite, use a String type. If
+ you'd like them to return datetime objects anyway despite
+ their accepting strings as input, make a TypeDecorator around
+ String - SQLA doesn't encourage this pattern.
+
+ .. change::
+ :tags: extensions
+ :tickets: 1096
+
+ Declarative supports a __table_args__ class variable, which is
+ either a dictionary, or tuple of the form (arg1, arg2, ...,
+ {kwarg1:value, ...}) which contains positional + kw arguments
+ to be passed to the Table constructor.
+
+.. changelog::
+ :version: 0.5beta1
+ :released: Thu Jun 12 2008
+
+ .. change::
+ :tags:
+ :tickets:
+
+ The "__init__" trigger/decorator added by mapper now attempts
+ to exactly mirror the argument signature of the original
+ __init__. The pass-through for '_sa_session' is no longer
+ implicit- you must allow for this keyword argument in your
+ constructor.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ ClassState is renamed to ClassManager.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ Classes may supply their own InstrumentationManager by
+ providing a __sa_instrumentation_manager__ property.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ Custom instrumentation may use any mechanism to associate a
+ ClassManager with a class and an InstanceState with an
+ instance. Attributes on those objects are still the default
+ association mechanism used by SQLAlchemy's native
+ instrumentation.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ Moved entity_name, _sa_session_id, and _instance_key from the
+ instance object to the instance state. These values are still
+ available in the old way, which is now deprecated, using
+ descriptors attached to the class. A deprecation warning will
+ be issued when accessed.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ The _prepare_instrumentation alias for prepare_instrumentation
+ has been removed.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ sqlalchemy.exceptions has been renamed to sqlalchemy.exc. The
+ module may be imported under either name.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ ORM-related exceptions are now defined in sqlalchemy.orm.exc.
+ ConcurrentModificationError, FlushError, and
+ UnmappedColumnError compatibility aliases are installed in
+ sqlalchemy.exc during the import of sqlalchemy.orm.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ sqlalchemy.logging has been renamed to sqlalchemy.log.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ The transitional sqlalchemy.log.SADeprecationWarning alias for
+ the warning's definition in sqlalchemy.exc has been removed.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ exc.AssertionError has been removed and usage replaced with
+ Python's built-in AssertionError.
+
+ .. change::
+ :tags:
+ :tickets:
+
+ The behavior of MapperExtensions attached to multiple,
+ entity_name= primary mappers for a single class has been
+ altered. The first mapper() defined for a class is the only
+ mapper eligible for the MapperExtension 'instrument_class',
+ 'init_instance' and 'init_failed' events. This is backwards
+ incompatible; previously the extensions of last mapper defined
+ would receive these events.
+
+ .. change::
+ :tags: firebird
+ :tickets:
+
+ Added support for returning values from inserts (2.0+ only),
+ updates and deletes (2.1+ only).
+
+ .. change::
+ :tags: general
+ :tickets:
+
+ global "propigate"->"propagate" change.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ polymorphic_union() function respects the "key" of each
+ Column if they differ from the column's name.
+
+ .. change::
+ :tags: orm
+ :tickets: 1199
+
+ Fixed 0.4-only bug preventing composite columns
+ from working properly with inheriting mappers
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Fixed RLock-related bug in mapper which could deadlock upon
+ reentrant mapper compile() calls, something that occurs when
+ using declarative constructs inside of ForeignKey objects.
+ Ported from 0.5.
+
+ .. change::
+ :tags: orm
+ :tickets: 1213
+
+ Fixed bug in composite types which prevented a primary-key
+ composite type from being mutated.
+
+ .. change::
+ :tags: orm
+ :tickets: 976
+
+ Added ScopedSession.is_active accessor.
+
+ .. change::
+ :tags: orm
+ :tickets: 939
+
+ Class-bound accessor can be used as the argument to
+ relation() order_by.
+
+ .. change::
+ :tags: orm
+ :tickets: 1072
+
+ Fixed shard_id argument on ShardedSession.execute().
+
+ .. change::
+ :tags: sql
+ :tickets: 1246
+
+ Connection.invalidate() checks for closed status
+ to avoid attribute errors.
+
+ .. change::
+ :tags: sql
+ :tickets: 1094
+
+ NullPool supports reconnect on failure behavior.
+
+ .. change::
+ :tags: sql
+ :tickets: 1299
+
+ The per-dialect cache used by TypeEngine to cache
+ dialect-specific types is now a WeakKeyDictionary.
+ This to prevent dialect objects from
+ being referenced forever for an application that
+ creates an arbitrarily large number of engines
+ or dialects. There is a small performance penalty
+ which will be resolved in 0.6.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Fixed SQLite reflection methods so that non-present
+ cursor.description, which triggers an auto-cursor
+ close, will be detected so that no results doesn't
+ fail on recent versions of pysqlite which raise
+ an error when fetchone() called with no rows present.
+
+ .. change::
+ :tags: postgres
+ :tickets: 714
+
+ Added Index reflection support to Postgres, using a
+ great patch we long neglected, submitted by
+ Ken Kuhlman.
+
+ .. change::
+ :tags: mysql
+ :tickets: 1241
+
+ Fixed bug in exception raise when FK columns not present
+ during reflection.
+
+ .. change::
+ :tags: oracle
+ :tickets: 1265
+
+ Fixed bug which was preventing out params of certain types
+ from being received; thanks a ton to huddlej at wwu.edu !
--- /dev/null
+
+==============
+0.6 Changelog
+==============
+
+
+.. changelog::
+ :version: 0.6.6
+ :released: Sat Jan 08 2011
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Fixed bug whereby a non-"mutable" attribute modified event
+ which occurred on an object that was clean except for
+ preceding mutable attribute changes would fail to strongly
+ reference itself in the identity map. This would cause the
+ object to be garbage collected, losing track of any changes
+ that weren't previously saved in the "mutable changes"
+ dictionary.
+
+ .. change::
+ :tags: orm
+ :tickets: 2013
+
+ Fixed bug whereby "passive_deletes='all'" wasn't passing
+ the correct symbols to lazy loaders during flush, thereby
+ causing an unwarranted load.
+
+ .. change::
+ :tags: orm
+ :tickets: 1997
+
+ Fixed bug which prevented composite mapped
+ attributes from being used on a mapped select statement.. Note the workings of composite are slated to
+ change significantly in 0.7.
+
+ .. change::
+ :tags: orm
+ :tickets: 1976
+
+ active_history flag also added to composite().
+ The flag has no effect in 0.6, but is instead
+ a placeholder flag for forwards compatibility,
+ as it applies in 0.7 for composites.
+
+ .. change::
+ :tags: orm
+ :tickets: 2002
+
+ Fixed uow bug whereby expired objects passed to
+ Session.delete() would not have unloaded references
+ or collections taken into account when deleting
+ objects, despite passive_deletes remaining at
+ its default of False.
+
+ .. change::
+ :tags: orm
+ :tickets: 1987
+
+ A warning is emitted when version_id_col is specified
+ on an inheriting mapper when the inherited mapper
+ already has one, if those column expressions are not
+ the same.
+
+ .. change::
+ :tags: orm
+ :tickets: 1954
+
+ "innerjoin" flag doesn't take effect along the chain
+ of joinedload() joins if a previous join in that chain
+ is an outer join, thus allowing primary rows without
+ a referenced child row to be correctly returned
+ in results.
+
+ .. change::
+ :tags: orm
+ :tickets: 1964
+
+ Fixed bug regarding "subqueryload" strategy whereby
+ strategy would fail if the entity was an aliased()
+ construct.
+
+ .. change::
+ :tags: orm
+ :tickets: 2014
+
+ Fixed bug regarding "subqueryload" strategy whereby
+ the join would fail if using a multi-level load
+ of the form from A->joined-subclass->C
+
+ .. change::
+ :tags: orm
+ :tickets: 1968
+
+ Fixed indexing of Query objects by -1. It was erroneously
+ transformed to the empty slice -1:0 that resulted in
+ IndexError.
+
+ .. change::
+ :tags: orm
+ :tickets: 1971
+
+ The mapper argument "primary_key" can be passed as a
+ single column as well as a list or tuple.
+ The documentation examples that illustrated it as a
+ scalar value have been changed to lists.
+
+ .. change::
+ :tags: orm
+ :tickets: 1961
+
+ Added active_history flag to relationship()
+ and column_property(), forces attribute events to
+ always load the "old" value, so that it's available to
+ attributes.get_history().
+
+ .. change::
+ :tags: orm
+ :tickets: 1977
+
+ Query.get() will raise if the number of params
+ in a composite key is too large, as well as too
+ small.
+
+ .. change::
+ :tags: orm
+ :tickets: 1992
+
+ Backport of "optimized get" fix from 0.7,
+ improves the generation of joined-inheritance
+ "load expired row" behavior.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ A little more verbiage to the "primaryjoin" error,
+ in an unusual condition that the join condition
+ "works" for viewonly but doesn't work for non-viewonly,
+ and foreign_keys wasn't used - adds "foreign_keys" to
+ the suggestion. Also add "foreign_keys" to the
+ suggestion for the generic "direction" error.
+
+ .. change::
+ :tags: sql
+ :tickets: 1984
+
+ Fixed operator precedence rules for multiple
+ chains of a single non-associative operator.
+ I.e. "x - (y - z)" will compile as "x - (y - z)"
+ and not "x - y - z". Also works with labels,
+ i.e. "x - (y - z).label('foo')"
+
+ .. change::
+ :tags: sql
+ :tickets: 1967
+
+ The 'info' attribute of Column is copied during
+ Column.copy(), i.e. as occurs when using columns
+ in declarative mixins.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Added a bind processor for booleans which coerces
+ to int, for DBAPIs such as pymssql that naively call
+ str() on values.
+
+ .. change::
+ :tags: sql
+ :tickets: 2000
+
+ CheckConstraint will copy its 'initially', 'deferrable',
+ and '_create_rule' attributes within a copy()/tometadata()
+
+ .. change::
+ :tags: engine
+ :tickets:
+
+ The "unicode warning" against non-unicode bind data
+ is now raised only when the
+ Unicode type is used explictly; not when
+ convert_unicode=True is used on the engine
+ or String type.
+
+ .. change::
+ :tags: engine
+ :tickets: 1978
+
+ Fixed memory leak in C version of Decimal result
+ processor.
+
+ .. change::
+ :tags: engine
+ :tickets: 1871
+
+ Implemented sequence check capability for the C
+ version of RowProxy, as well as 2.7 style
+ "collections.Sequence" registration for RowProxy.
+
+ .. change::
+ :tags: engine
+ :tickets: 1998
+
+ Threadlocal engine methods rollback(), commit(),
+ prepare() won't raise if no transaction is in progress;
+ this was a regression introduced in 0.6.
+
+ .. change::
+ :tags: engine
+ :tickets: 2004
+
+ Threadlocal engine returns itself upon begin(),
+ begin_nested(); engine then implements contextmanager
+ methods to allow the "with" statement.
+
+ .. change::
+ :tags: postgresql
+ :tickets: 1984
+
+ Single element tuple expressions inside an IN clause
+ parenthesize correctly, also from
+
+ .. change::
+ :tags: postgresql
+ :tickets: 1955
+
+ Ensured every numeric, float, int code, scalar + array,
+ are recognized by psycopg2 and pg8000's "numeric"
+ base type.
+
+ .. change::
+ :tags: postgresql
+ :tickets: 1956
+
+ Added as_uuid=True flag to the UUID type, will receive
+ and return values as Python UUID() objects rather than
+ strings. Currently, the UUID type is only known to
+ work with psycopg2.
+
+ .. change::
+ :tags: postgresql
+ :tickets: 1989
+
+ Fixed bug whereby KeyError would occur with non-ENUM
+ supported PG versions after a pool dispose+recreate
+ would occur.
+
+ .. change::
+ :tags: mysql
+ :tickets: 1960
+
+ Fixed error handling for Jython + zxjdbc, such that
+ has_table() property works again. Regression from
+ 0.6.3 (we don't have a Jython buildbot, sorry)
+
+ .. change::
+ :tags: sqlite
+ :tickets: 1851
+
+ The REFERENCES clause in a CREATE TABLE that includes
+ a remote schema to another table with the same schema
+ name now renders the remote name without
+ the schema clause, as required by SQLite.
+
+ .. change::
+ :tags: sqlite
+ :tickets:
+
+ On the same theme, the REFERENCES clause in a CREATE TABLE
+ that includes a remote schema to a *different* schema
+ than that of the parent table doesn't render at all,
+ as cross-schema references do not appear to be supported.
+
+ .. change::
+ :tags: mssql
+ :tickets: 1770
+
+ The rewrite of index reflection in was
+ unfortunately not tested correctly, and returned incorrect
+ results. This regression is now fixed.
+
+ .. change::
+ :tags: oracle
+ :tickets: 1953
+
+ The cx_oracle "decimal detection" logic, which takes place
+ for for result set columns with ambiguous numeric characteristics,
+ now uses the decimal point character determined by the locale/
+ NLS_LANG setting, using an on-first-connect detection of
+ this character. cx_oracle 5.0.3 or greater is also required
+ when using a non-period-decimal-point NLS_LANG setting..
+
+ .. change::
+ :tags: firebird
+ :tickets: 2012
+
+ Firebird numeric type now checks for Decimal explicitly,
+ lets float() pass right through, thereby allowing
+ special values such as float('inf').
+
+ .. change::
+ :tags: declarative
+ :tickets: 1972
+
+ An error is raised if __table_args__ is not in tuple
+ or dict format, and is not None.
+
+ .. change::
+ :tags: sqlsoup
+ :tickets: 1975
+
+ Added "map_to()" method to SqlSoup, which is a "master"
+ method which accepts explicit arguments for each aspect of
+ the selectable and mapping, including a base class per
+ mapping.
+
+ .. change::
+ :tags: sqlsoup
+ :tickets:
+
+ Mapped selectables used with the map(), with_labels(),
+ join() methods no longer put the given argument into the
+ internal "cache" dictionary. Particularly since the
+ join() and select() objects are created in the method
+ itself this was pretty much a pure memory leaking behavior.
+
+ .. change::
+ :tags: examples
+ :tickets:
+
+ The versioning example now supports detection of changes
+ in an associated relationship().
+
+.. changelog::
+ :version: 0.6.5
+ :released: Sun Oct 24 2010
+
+ .. change::
+ :tags: orm
+ :tickets: 1914
+
+ Added a new "lazyload" option "immediateload".
+ Issues the usual "lazy" load operation automatically
+ as the object is populated. The use case
+ here is when loading objects to be placed in
+ an offline cache, or otherwise used after
+ the session isn't available, and straight 'select'
+ loading, not 'joined' or 'subquery', is desired.
+
+ .. change::
+ :tags: orm
+ :tickets: 1920
+
+ New Query methods: query.label(name), query.as_scalar(),
+ return the query's statement as a scalar subquery
+ with /without label;
+ query.with_entities(*ent), replaces the SELECT list of
+ the query with new entities.
+ Roughly equivalent to a generative form of query.values()
+ which accepts mapped entities as well as column
+ expressions.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Fixed recursion bug which could occur when moving
+ an object from one reference to another, with
+ backrefs involved, where the initiating parent
+ was a subclass (with its own mapper) of the
+ previous parent.
+
+ .. change::
+ :tags: orm
+ :tickets: 1918
+
+ Fixed a regression in 0.6.4 which occurred if you
+ passed an empty list to "include_properties" on
+ mapper()
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Fixed labeling bug in Query whereby the NamedTuple
+ would mis-apply labels if any of the column
+ expressions were un-labeled.
+
+ .. change::
+ :tags: orm
+ :tickets: 1925
+
+ Patched a case where query.join() would adapt the
+ right side to the right side of the left's join
+ inappropriately
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Query.select_from() has been beefed up to help
+ ensure that a subsequent call to query.join()
+ will use the select_from() entity, assuming it's
+ a mapped entity and not a plain selectable,
+ as the default "left" side, not the first entity
+ in the Query object's list of entities.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ The exception raised by Session when it is used
+ subsequent to a subtransaction rollback (which is what
+ happens when a flush fails in autocommit=False mode) has
+ now been reworded (this is the "inactive due to a
+ rollback in a subtransaction" message). In particular,
+ if the rollback was due to an exception during flush(),
+ the message states this is the case, and reiterates the
+ string form of the original exception that occurred
+ during flush. If the session is closed due to explicit
+ usage of subtransactions (not very common), the message
+ just states this is the case.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ The exception raised by Mapper when repeated requests to
+ its initialization are made after initialization already
+ failed no longer assumes the "hasattr" case, since
+ there's other scenarios in which this message gets
+ emitted, and the message also does not compound onto
+ itself multiple times - you get the same message for
+ each attempt at usage. The misnomer "compiles" is being
+ traded out for "initialize".
+
+ .. change::
+ :tags: orm
+ :tickets: 1935
+
+ Fixed bug in query.update() where 'evaluate' or 'fetch'
+ expiration would fail if the column expression key was
+ a class attribute with a different keyname as the
+ actual column name.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Added an assertion during flush which ensures
+ that no NULL-holding identity keys were generated
+ on "newly persistent" objects.
+ This can occur when user defined code inadvertently
+ triggers flushes on not-fully-loaded objects.
+
+ .. change::
+ :tags: orm
+ :tickets: 1910
+
+ lazy loads for relationship attributes now use
+ the current state, not the "committed" state,
+ of foreign and primary key attributes
+ when issuing SQL, if a flush is not in process.
+ Previously, only the database-committed state would
+ be used. In particular, this would cause a many-to-one
+ get()-on-lazyload operation to fail, as autoflush
+ is not triggered on these loads when the attributes are
+ determined and the "committed" state may not be
+ available.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ A new flag on relationship(), load_on_pending, allows
+ the lazy loader to fire off on pending objects without a
+ flush taking place, as well as a transient object that's
+ been manually "attached" to the session. Note that this
+ flag blocks attribute events from taking place when an
+ object is loaded, so backrefs aren't available until
+ after a flush. The flag is only intended for very
+ specific use cases.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Another new flag on relationship(), cascade_backrefs,
+ disables the "save-update" cascade when the event was
+ initiated on the "reverse" side of a bidirectional
+ relationship. This is a cleaner behavior so that
+ many-to-ones can be set on a transient object without
+ it getting sucked into the child object's session,
+ while still allowing the forward collection to
+ cascade. We *might* default this to False in 0.7.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Slight improvement to the behavior of
+ "passive_updates=False" when placed only on the
+ many-to-one side of a relationship; documentation has
+ been clarified that passive_updates=False should really
+ be on the one-to-many side.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Placing passive_deletes=True on a many-to-one emits
+ a warning, since you probably intended to put it on
+ the one-to-many side.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Fixed bug that would prevent "subqueryload" from
+ working correctly with single table inheritance
+ for a relationship from a subclass - the "where
+ type in (x, y, z)" only gets placed on the inside,
+ instead of repeatedly.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ When using from_self() with single table inheritance,
+ the "where type in (x, y, z)" is placed on the outside
+ of the query only, instead of repeatedly. May make
+ some more adjustments to this.
+
+ .. change::
+ :tags: orm
+ :tickets: 1924
+
+ scoped_session emits a warning when configure() is
+ called if a Session is already present (checks only the
+ current thread)
+
+ .. change::
+ :tags: orm
+ :tickets: 1932
+
+ reworked the internals of mapper.cascade_iterator() to
+ cut down method calls by about 9% in some circumstances.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Fixed bug in TypeDecorator whereby the dialect-specific
+ type was getting pulled in to generate the DDL for a
+ given type, which didn't always return the correct result.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ TypeDecorator can now have a fully constructed type
+ specified as its "impl", in addition to a type class.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ TypeDecorator will now place itself as the resulting
+ type for a binary expression where the type coercion
+ rules would normally return its impl type - previously,
+ a copy of the impl type would be returned which would
+ have the TypeDecorator embedded into it as the "dialect"
+ impl, this was probably an unintentional way of achieving
+ the desired effect.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ TypeDecorator.load_dialect_impl() returns "self.impl" by
+ default, i.e. not the dialect implementation type of
+ "self.impl". This to support compilation correctly.
+ Behavior can be user-overridden in exactly the same way
+ as before to the same effect.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Added type_coerce(expr, type_) expression element.
+ Treats the given expression as the given type when evaluating
+ expressions and processing result rows, but does not
+ affect the generation of SQL, other than an anonymous
+ label.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Table.tometadata() now copies Index objects associated
+ with the Table as well.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Table.tometadata() issues a warning if the given Table
+ is already present in the target MetaData - the existing
+ Table object is returned.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ An informative error message is raised if a Column
+ which has not yet been assigned a name, i.e. as in
+ declarative, is used in a context where it is
+ exported to the columns collection of an enclosing
+ select() construct, or if any construct involving
+ that column is compiled before its name is
+ assigned.
+
+ .. change::
+ :tags: sql
+ :tickets: 1862
+
+ as_scalar(), label() can be called on a selectable
+ which contains a Column that is not yet named.
+
+ .. change::
+ :tags: sql
+ :tickets: 1907
+
+ Fixed recursion overflow which could occur when operating
+ with two expressions both of type "NullType", but
+ not the singleton NULLTYPE instance.
+
+ .. change::
+ :tags: declarative
+ :tickets: 1922
+
+ @classproperty (soon/now @declared_attr) takes effect for
+ __mapper_args__, __table_args__, __tablename__ on
+ a base class that is not a mixin, as well as mixins.
+
+ .. change::
+ :tags: declarative
+ :tickets: 1915
+
+ @classproperty 's official name/location for usage
+ with declarative is sqlalchemy.ext.declarative.declared_attr.
+ Same thing, but moving there since it is more of a
+ "marker" that's specific to declararative,
+ not just an attribute technique.
+
+ .. change::
+ :tags: declarative
+ :tickets: 1931, 1930
+
+ Fixed bug whereby columns on a mixin wouldn't propagate
+ correctly to a single-table, or joined-table,
+ inheritance scheme where the attribute name is
+ different than that of the column.,.
+
+ .. change::
+ :tags: declarative
+ :tickets:
+
+ A mixin can now specify a column that overrides
+ a column of the same name associated with a superclass.
+ Thanks to Oystein Haaland.
+
+ .. change::
+ :tags: engine
+ :tickets:
+
+ Fixed a regression in 0.6.4 whereby the change that
+ allowed cursor errors to be raised consistently broke
+ the result.lastrowid accessor. Test coverage has
+ been added for result.lastrowid. Note that lastrowid
+ is only supported by Pysqlite and some MySQL drivers,
+ so isn't super-useful in the general case.
+
+ .. change::
+ :tags: engine
+ :tickets:
+
+ the logging message emitted by the engine when
+ a connection is first used is now "BEGIN (implicit)"
+ to emphasize that DBAPI has no explicit begin().
+
+ .. change::
+ :tags: engine
+ :tickets: 1936
+
+ added "views=True" option to metadata.reflect(),
+ will add the list of available views to those
+ being reflected.
+
+ .. change::
+ :tags: engine
+ :tickets: 1899
+
+ engine_from_config() now accepts 'debug' for
+ 'echo', 'echo_pool', 'force' for 'convert_unicode',
+ boolean values for 'use_native_unicode'.
+
+ .. change::
+ :tags: postgresql
+ :tickets:
+
+ Added "as_tuple" flag to ARRAY type, returns results
+ as tuples instead of lists to allow hashing.
+
+ .. change::
+ :tags: postgresql
+ :tickets: 1933
+
+ Fixed bug which prevented "domain" built from a
+ custom type such as "enum" from being reflected.
+
+ .. change::
+ :tags: mysql
+ :tickets: 1940
+
+ Fixed bug involving reflection of CURRENT_TIMESTAMP
+ default used with ON UPDATE clause, thanks to
+ Taavi Burns
+
+ .. change::
+ :tags: oracle
+ :tickets: 1878
+
+ The implicit_retunring argument to create_engine()
+ is now honored regardless of detected version of
+ Oracle. Previously, the flag would be forced
+ to False if server version info was < 10.
+
+ .. change::
+ :tags: mssql
+ :tickets: 1946
+
+ Fixed reflection bug which did not properly handle
+ reflection of unknown types.
+
+ .. change::
+ :tags: mssql
+ :tickets: 1943
+
+ Fixed bug where aliasing of tables with "schema" would
+ fail to compile properly.
+
+ .. change::
+ :tags: mssql
+ :tickets: 1770
+
+ Rewrote the reflection of indexes to use sys.
+ catalogs, so that column names of any configuration
+ (spaces, embedded commas, etc.) can be reflected.
+ Note that reflection of indexes requires SQL
+ Server 2005 or greater.
+
+ .. change::
+ :tags: mssql
+ :tickets: 1952
+
+ mssql+pymssql dialect now honors the "port" portion
+ of the URL instead of discarding it.
+
+ .. change::
+ :tags: informix
+ :tickets: 1906
+
+ *Major* cleanup / modernization of the Informix
+ dialect for 0.6, courtesy Florian Apolloner.
+
+ .. change::
+ :tags: tests
+ :tickets:
+
+ the NoseSQLAlchemyPlugin has been moved to a
+ new package "sqlalchemy_nose" which installs
+ along with "sqlalchemy". This so that the "nosetests"
+ script works as always but also allows the
+ --with-coverage option to turn on coverage before
+ SQLAlchemy modules are imported, allowing coverage
+ to work correctly.
+
+ .. change::
+ :tags: misc
+ :tickets: 1890
+
+ CircularDependencyError now has .cycles and .edges
+ members, which are the set of elements involved in
+ one or more cycles, and the set of edges as 2-tuples.
+
+.. changelog::
+ :version: 0.6.4
+ :released: Tue Sep 07 2010
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ The name ConcurrentModificationError has been
+ changed to StaleDataError, and descriptive
+ error messages have been revised to reflect
+ exactly what the issue is. Both names will
+ remain available for the forseeable future
+ for schemes that may be specifying
+ ConcurrentModificationError in an "except:"
+ clause.
+
+ .. change::
+ :tags: orm
+ :tickets: 1891
+
+ Added a mutex to the identity map which mutexes
+ remove operations against iteration methods,
+ which now pre-buffer before returning an
+ iterable. This because asyncrhonous gc
+ can remove items via the gc thread at any time.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ The Session class is now present in sqlalchemy.orm.*.
+ We're moving away from the usage of create_session(),
+ which has non-standard defaults, for those situations
+ where a one-step Session constructor is desired. Most
+ users should stick with sessionmaker() for general use,
+ however.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ query.with_parent() now accepts transient objects
+ and will use the non-persistent values of their pk/fk
+ attributes in order to formulate the criterion.
+ Docs are also clarified as to the purpose of with_parent().
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ The include_properties and exclude_properties arguments
+ to mapper() now accept Column objects as members in
+ addition to strings. This so that same-named Column
+ objects, such as those within a join(), can be
+ disambiguated.
+
+ .. change::
+ :tags: orm
+ :tickets: 1896
+
+ A warning is now emitted if a mapper is created against a
+ join or other single selectable that includes multiple
+ columns with the same name in its .c. collection,
+ and those columns aren't explictly named as part of
+ the same or separate attributes (or excluded).
+ In 0.7 this warning will be an exception. Note that
+ this warning is not emitted when the combination occurs
+ as a result of inheritance, so that attributes
+ still allow being overridden naturally.. In 0.7 this will be improved further.
+
+ .. change::
+ :tags: orm
+ :tickets: 1896
+
+ The primary_key argument to mapper() can now specify
+ a series of columns that are only a subset of
+ the calculated "primary key" columns of the mapped
+ selectable, without an error being raised. This
+ helps for situations where a selectable's effective
+ primary key is simpler than the number of columns
+ in the selectable that are actually marked as
+ "primary_key", such as a join against two
+ tables on their primary key columns.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ An object that's been deleted now gets a flag
+ 'deleted', which prohibits the object from
+ being re-add()ed to the session, as previously
+ the object would live in the identity map
+ silently until its attributes were accessed.
+ The make_transient() function now resets this
+ flag along with the "key" flag.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ make_transient() can be safely called on an
+ already transient instance.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ a warning is emitted in mapper() if the polymorphic_on
+ column is not present either in direct or derived
+ form in the mapped selectable or in the
+ with_polymorphic selectable, instead of silently
+ ignoring it. Look for this to become an
+ exception in 0.7.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Another pass through the series of error messages
+ emitted when relationship() is configured with
+ ambiguous arguments. The "foreign_keys"
+ setting is no longer mentioned, as it is almost
+ never needed and it is preferable users set up
+ correct ForeignKey metadata, which is now the
+ recommendation. If 'foreign_keys'
+ is used and is incorrect, the message suggests
+ the attribute is probably unnecessary. Docs
+ for the attribute are beefed up. This
+ because all confused relationship() users on the
+ ML appear to be attempting to use foreign_keys
+ due to the message, which only confuses them
+ further since Table metadata is much clearer.
+
+ .. change::
+ :tags: orm
+ :tickets: 1877
+
+ If the "secondary" table has no ForeignKey metadata
+ and no foreign_keys is set, even though the
+ user is passing screwed up information, it is assumed
+ that primary/secondaryjoin expressions should
+ consider only and all cols in "secondary" to be
+ foreign. It's not possible with "secondary" for
+ the foreign keys to be elsewhere in any case.
+ A warning is now emitted instead of an error,
+ and the mapping succeeds.
+
+ .. change::
+ :tags: orm
+ :tickets: 1856
+
+ Moving an o2m object from one collection to
+ another, or vice versa changing the referenced
+ object by an m2o, where the foreign key is also a
+ member of the primary key, will now be more
+ carefully checked during flush if the change in
+ value of the foreign key on the "many" side is the
+ result of a change in the primary key of the "one"
+ side, or if the "one" is just a different object.
+ In one case, a cascade-capable DB would have
+ cascaded the value already and we need to look at
+ the "new" PK value to do an UPDATE, in the other we
+ need to continue looking at the "old". We now look
+ at the "old", assuming passive_updates=True,
+ unless we know it was a PK switch that
+ triggered the change.
+
+ .. change::
+ :tags: orm
+ :tickets: 1857
+
+ The value of version_id_col can be changed
+ manually, and this will result in an UPDATE
+ of the row. Versioned UPDATEs and DELETEs
+ now use the "committed" value of the
+ version_id_col in the WHERE clause and
+ not the pending changed value. The
+ version generator is also bypassed if
+ manual changes are present on the attribute.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Repaired the usage of merge() when used with
+ concrete inheriting mappers. Such mappers frequently
+ have so-called "concrete" attributes, which are
+ subclass attributes that "disable" propagation from
+ the parent - these needed to allow a merge()
+ operation to pass through without effect.
+
+ .. change::
+ :tags: orm
+ :tickets: 1863
+
+ Specifying a non-column based argument
+ for column_mapped_collection, including string,
+ text() etc., will raise an error message that
+ specifically asks for a column element, no longer
+ misleads with incorrect information about
+ text() or literal().
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Similarly, for relationship(), foreign_keys,
+ remote_side, order_by - all column-based
+ expressions are enforced - lists of strings
+ are explicitly disallowed since this is a
+ very common error
+
+ .. change::
+ :tags: orm
+ :tickets: 1864
+
+ Dynamic attributes don't support collection
+ population - added an assertion for when
+ set_committed_value() is called, as well as
+ when joinedload() or subqueryload() options
+ are applied to a dynamic attribute, instead
+ of failure / silent failure.
+
+ .. change::
+ :tags: orm
+ :tickets: 1852
+
+ Fixed bug whereby generating a Query derived
+ from one which had the same column repeated
+ with different label names, typically
+ in some UNION situations, would fail to
+ propagate the inner columns completely to
+ the outer query.
+
+ .. change::
+ :tags: orm
+ :tickets: 1881
+
+ object_session() raises the proper
+ UnmappedInstanceError when presented with an
+ unmapped instance.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Applied further memoizations to calculated Mapper
+ properties, with significant (~90%) runtime mapper.py
+ call count reduction in heavily polymorphic mapping
+ configurations.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ mapper _get_col_to_prop private method used
+ by the versioning example is deprecated;
+ now use mapper.get_property_by_column() which
+ will remain the public method for this.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ the versioning example works correctly now
+ if versioning on a col that was formerly
+ NULL.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Calling execute() on an alias() construct is pending
+ deprecation for 0.7, as it is not itself an
+ "executable" construct. It currently "proxies" its
+ inner element and is conditionally "executable" but
+ this is not the kind of ambiguity we like these days.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ The execute() and scalar() methods of ClauseElement
+ are now moved appropriately to the Executable
+ subclass. ClauseElement.execute()/ scalar() are still
+ present and are pending deprecation in 0.7, but note
+ these would always raise an error anyway if you were
+ not an Executable (unless you were an alias(), see
+ previous note).
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Added basic math expression coercion for
+ Numeric->Integer,
+ so that resulting type is Numeric regardless
+ of the direction of the expression.
+
+ .. change::
+ :tags: sql
+ :tickets: 1855
+
+ Changed the scheme used to generate truncated
+ "auto" index names when using the "index=True"
+ flag on Column. The truncation only takes
+ place with the auto-generated name, not one
+ that is user-defined (an error would be
+ raised instead), and the truncation scheme
+ itself is now based on a fragment of an md5
+ hash of the identifier name, so that multiple
+ indexes on columns with similar names still
+ have unique names.
+
+ .. change::
+ :tags: sql
+ :tickets: 1412
+
+ The generated index name also is based on
+ a "max index name length" attribute which is
+ separate from the "max identifier length" -
+ this to appease MySQL who has a max length
+ of 64 for index names, separate from their
+ overall max length of 255.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ the text() construct, if placed in a column
+ oriented situation, will at least return NULLTYPE
+ for its type instead of None, allowing it to
+ be used a little more freely for ad-hoc column
+ expressions than before. literal_column()
+ is still the better choice, however.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Added full description of parent table/column,
+ target table/column in error message raised when
+ ForeignKey can't resolve target.
+
+ .. change::
+ :tags: sql
+ :tickets: 1865
+
+ Fixed bug whereby replacing composite foreign key
+ columns in a reflected table would cause an attempt
+ to remove the reflected constraint from the table
+ a second time, raising a KeyError.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ the _Label construct, i.e. the one that is produced
+ whenever you say somecol.label(), now counts itself
+ in its "proxy_set" unioned with that of it's
+ contained column's proxy set, instead of
+ directly returning that of the contained column.
+ This allows column correspondence
+ operations which depend on the identity of the
+ _Labels themselves to return the correct result
+
+ .. change::
+ :tags: sql
+ :tickets: 1852
+
+ fixes ORM bug.
+
+ .. change::
+ :tags: engine
+ :tickets:
+
+ Calling fetchone() or similar on a result that
+ has already been exhausted, has been closed,
+ or is not a result-returning result now
+ raises ResourceClosedError, a subclass of
+ InvalidRequestError, in all cases, regardless
+ of backend. Previously, some DBAPIs would
+ raise ProgrammingError (i.e. pysqlite), others
+ would return None leading to downstream breakages
+ (i.e. MySQL-python).
+
+ .. change::
+ :tags: engine
+ :tickets: 1894
+
+ Fixed bug in Connection whereby if a "disconnect"
+ event occurred in the "initialize" phase of the
+ first connection pool connect, an AttributeError
+ would be raised when the Connection would attempt
+ to invalidate the DBAPI connection.
+
+ .. change::
+ :tags: engine
+ :tickets:
+
+ Connection, ResultProxy, as well as Session use
+ ResourceClosedError for all "this
+ connection/transaction/result is closed" types of
+ errors.
+
+ .. change::
+ :tags: engine
+ :tickets:
+
+ Connection.invalidate() can be called more than
+ once and subsequent calls do nothing.
+
+ .. change::
+ :tags: declarative
+ :tickets:
+
+ if @classproperty is used with a regular class-bound
+ mapper property attribute, it will be called to get the
+ actual attribute value during initialization. Currently,
+ there's no advantage to using @classproperty on a column
+ or relationship attribute of a declarative class that
+ isn't a mixin - evaluation is at the same time as if
+ @classproperty weren't used. But here we at least allow
+ it to function as expected.
+
+ .. change::
+ :tags: declarative
+ :tickets:
+
+ Fixed bug where "Can't add additional column" message
+ would display the wrong name.
+
+ .. change::
+ :tags: postgresql
+ :tickets:
+
+ Fixed the psycopg2 dialect to use its
+ set_isolation_level() method instead of relying
+ upon the base "SET SESSION ISOLATION" command,
+ as psycopg2 resets the isolation level on each new
+ transaction otherwise.
+
+ .. change::
+ :tags: mssql
+ :tickets:
+
+ Fixed "default schema" query to work with
+ pymssql backend.
+
+ .. change::
+ :tags: firebird
+ :tickets:
+
+ Fixed bug whereby a column default would fail to
+ reflect if the "default" keyword were lower case.
+
+ .. change::
+ :tags: oracle
+ :tickets: 1879
+
+ Added ROWID type to the Oracle dialect, for those
+ cases where an explicit CAST might be needed.
+
+ .. change::
+ :tags: oracle
+ :tickets: 1867
+
+ Oracle reflection of indexes has been tuned so
+ that indexes which include some or all primary
+ key columns, but not the same set of columns
+ as that of the primary key, are reflected.
+ Indexes which contain the identical columns
+ as that of the primary key are skipped within
+ reflection, as the index in that case is assumed
+ to be the auto-generated primary key index.
+ Previously, any index with PK columns present
+ would be skipped. Thanks to Kent Bower
+ for the patch.
+
+ .. change::
+ :tags: oracle
+ :tickets: 1868
+
+ Oracle now reflects the names of primary key
+ constraints - also thanks to Kent Bower.
+
+ .. change::
+ :tags: informix
+ :tickets: 1904
+
+ Applied patches from to get
+ basic Informix functionality up again. We
+ rely upon end-user testing to ensure that
+ Informix is working to some degree.
+
+ .. change::
+ :tags: documentation
+ :tickets:
+
+ The docs have been reorganized such that the "API
+ Reference" section is gone - all the docstrings from
+ there which were public API are moved into the
+ context of the main doc section that talks about it.
+ Main docs divided into "SQLAlchemy Core" and
+ "SQLAlchemy ORM" sections, mapper/relationship docs
+ have been broken out. Lots of sections rewritten
+ and/or reorganized.
+
+ .. change::
+ :tags: examples
+ :tickets:
+
+ The beaker_caching example has been reorgnized
+ such that the Session, cache manager,
+ declarative_base are part of environment, and
+ custom cache code is portable and now within
+ "caching_query.py". This allows the example to
+ be easier to "drop in" to existing projects.
+
+ .. change::
+ :tags: examples
+ :tickets: 1887
+
+ the history_meta versioning recipe sets "unique=False"
+ when copying columns, so that the versioning
+ table handles multiple rows with repeating values.
+
+.. changelog::
+ :version: 0.6.3
+ :released: Thu Jul 15 2010
+
+ .. change::
+ :tags: orm
+ :tickets: 1845
+
+ Removed errant many-to-many load in unitofwork
+ which triggered unnecessarily on expired/unloaded
+ collections. This load now takes place only if
+ passive_updates is False and the parent primary
+ key has changed, or if passive_deletes is False
+ and a delete of the parent has occurred.
+
+ .. change::
+ :tags: orm
+ :tickets: 1853
+
+ Column-entities (i.e. query(Foo.id)) copy their
+ state more fully when queries are derived from
+ themselves + a selectable (i.e. from_self(),
+ union(), etc.), so that join() and such have the
+ correct state to work from.
+
+ .. change::
+ :tags: orm
+ :tickets: 1853
+
+ Fixed bug where Query.join() would fail if
+ querying a non-ORM column then joining without
+ an on clause when a FROM clause is already
+ present, now raises a checked exception the
+ same way it does when the clause is not
+ present.
+
+ .. change::
+ :tags: orm
+ :tickets: 1142
+
+ Improved the check for an "unmapped class",
+ including the case where the superclass is mapped
+ but the subclass is not. Any attempts to access
+ cls._sa_class_manager.mapper now raise
+ UnmappedClassError().
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Added "column_descriptions" accessor to Query,
+ returns a list of dictionaries containing
+ naming/typing information about the entities
+ the Query will return. Can be helpful for
+ building GUIs on top of ORM queries.
+
+ .. change::
+ :tags: mysql
+ :tickets: 1848
+
+ The _extract_error_code() method now works
+ correctly with each MySQL dialect (
+ MySQL-python, OurSQL, MySQL-Connector-Python,
+ PyODBC). Previously,
+ the reconnect logic would fail for OperationalError
+ conditions, however since MySQLdb and OurSQL
+ have their own reconnect feature, there was no
+ symptom for these drivers here unless one
+ watched the logs.
+
+ .. change::
+ :tags: oracle
+ :tickets: 1840
+
+ More tweaks to cx_oracle Decimal handling.
+ "Ambiguous" numerics with no decimal place
+ are coerced to int at the connection handler
+ level. The advantage here is that ints
+ come back as ints without SQLA type
+ objects being involved and without needless
+ conversion to Decimal first.
+
+ Unfortunately, some exotic subquery cases
+ can even see different types between
+ individual result rows, so the Numeric
+ handler, when instructed to return Decimal,
+ can't take full advantage of "native decimal"
+ mode and must run isinstance() on every value
+ to check if its Decimal already. Reopen of
+
+.. changelog::
+ :version: 0.6.2
+ :released: Tue Jul 06 2010
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Query.join() will check for a call of the
+ form query.join(target, clause_expression),
+ i.e. missing the tuple, and raise an informative
+ error message that this is the wrong calling form.
+
+ .. change::
+ :tags: orm
+ :tickets: 1824
+
+ Fixed bug regarding flushes on self-referential
+ bi-directional many-to-many relationships, where
+ two objects made to mutually reference each other
+ in one flush would fail to insert a row for both
+ sides. Regression from 0.5.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ the post_update feature of relationship() has been
+ reworked architecturally to integrate more closely
+ with the new 0.6 unit of work. The motivation
+ for the change is so that multiple "post update"
+ calls, each affecting different foreign key
+ columns of the same row, are executed in a single
+ UPDATE statement, rather than one UPDATE
+ statement per column per row. Multiple row
+ updates are also batched into executemany()s as
+ possible, while maintaining consistent row ordering.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Query.statement, Query.subquery(), etc. now transfer
+ the values of bind parameters, i.e. those specified
+ by query.params(), into the resulting SQL expression.
+ Previously the values would not be transferred
+ and bind parameters would come out as None.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Subquery-eager-loading now works with Query objects
+ which include params(), as well as get() Queries.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Can now call make_transient() on an instance that
+ is referenced by parent objects via many-to-one,
+ without the parent's foreign key value getting
+ temporarily set to None - this was a function
+ of the "detect primary key switch" flush handler.
+ It now ignores objects that are no longer
+ in the "persistent" state, and the parent's
+ foreign key identifier is left unaffected.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ query.order_by() now accepts False, which cancels
+ any existing order_by() state on the Query, allowing
+ subsequent generative methods to be called which do
+ not support ORDER BY. This is not the same as the
+ already existing feature of passing None, which
+ suppresses any existing order_by() settings, including
+ those configured on the mapper. False will make it
+ as though order_by() was never called, while
+ None is an active setting.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ An instance which is moved to "transient", has
+ an incomplete or missing set of primary key
+ attributes, and contains expired attributes, will
+ raise an InvalidRequestError if an expired attribute
+ is accessed, instead of getting a recursion overflow.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ The make_transient() function is now in the generated
+ documentation.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ make_transient() removes all "loader" callables from
+ the state being made transient, removing any
+ "expired" state - all unloaded attributes reset back
+ to undefined, None/empty on access.
+
+ .. change::
+ :tags: sql
+ :tickets: 1822
+
+ The warning emitted by the Unicode and String types
+ with convert_unicode=True no longer embeds the actual
+ value passed. This so that the Python warning
+ registry does not continue to grow in size, the warning
+ is emitted once as per the warning filter settings,
+ and large string values don't pollute the output.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Fixed bug that would prevent overridden clause
+ compilation from working for "annotated" expression
+ elements, which are often generated by the ORM.
+
+ .. change::
+ :tags: sql
+ :tickets: 1400
+
+ The argument to "ESCAPE" of a LIKE operator or similar
+ is passed through render_literal_value(), which may
+ implement escaping of backslashes.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Fixed bug in Enum type which blew away native_enum
+ flag when used with TypeDecorators or other adaption
+ scenarios.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Inspector hits bind.connect() when invoked to ensure
+ initialize has been called. the internal name ".conn"
+ is changed to ".bind", since that's what it is.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Modified the internals of "column annotation" such that
+ a custom Column subclass can safely override
+ _constructor to return Column, for the purposes of
+ making "configurational" column classes that aren't
+ involved in proxying, etc.
+
+ .. change::
+ :tags: sql
+ :tickets: 1829
+
+ Column.copy() takes along the "unique" attribute
+ among others, fixes regarding declarative
+ mixins
+
+ .. change::
+ :tags: postgresql
+ :tickets: 1400
+
+ render_literal_value() is overridden which escapes
+ backslashes, currently applies to the ESCAPE clause
+ of LIKE and similar expressions.
+ Ultimately this will have to detect the value of
+ "standard_conforming_strings" for full behavior.
+
+ .. change::
+ :tags: postgresql
+ :tickets: 1836
+
+ Won't generate "CREATE TYPE" / "DROP TYPE" if
+ using types.Enum on a PG version prior to 8.3 -
+ the supports_native_enum flag is fully
+ honored.
+
+ .. change::
+ :tags: mysql
+ :tickets: 1826
+
+ MySQL dialect doesn't emit CAST() for MySQL version
+ detected < 4.0.2. This allows the unicode
+ check on connect to proceed.
+
+ .. change::
+ :tags: mysql
+ :tickets:
+
+ MySQL dialect now detects NO_BACKSLASH_ESCAPES sql
+ mode, in addition to ANSI_QUOTES.
+
+ .. change::
+ :tags: mysql
+ :tickets: 1400
+
+ render_literal_value() is overridden which escapes
+ backslashes, currently applies to the ESCAPE clause
+ of LIKE and similar expressions. This behavior
+ is derived from detecting the value of
+ NO_BACKSLASH_ESCAPES.
+
+ .. change::
+ :tags: oracle
+ :tickets: 1819
+
+ Fixed ora-8 compatibility flags such that they
+ don't cache a stale value from before the first
+ database connection actually occurs.
+
+ .. change::
+ :tags: oracle
+ :tickets: 1840
+
+ Oracle's "native decimal" metadata begins to return
+ ambiguous typing information about numerics
+ when columns are embedded in subqueries as well
+ as when ROWNUM is consulted with subqueries, as we
+ do for limit/offset. We've added these ambiguous
+ conditions to the cx_oracle "convert to Decimal()"
+ handler, so that we receive numerics as Decimal
+ in more cases instead of as floats. These are
+ then converted, if requested, into Integer
+ or Float, or otherwise kept as the lossless
+ Decimal.
+
+ .. change::
+ :tags: mssql
+ :tickets: 1825
+
+ If server_version_info is outside the usual
+ range of (8, ), (9, ), (10, ), a warning is emitted
+ which suggests checking that the FreeTDS version
+ configuration is using 7.0 or 8.0, not 4.2.
+
+ .. change::
+ :tags: firebird
+ :tickets: 1823
+
+ Fixed incorrect signature in do_execute(), error
+ introduced in 0.6.1.
+
+ .. change::
+ :tags: firebird
+ :tickets: 1813
+
+ Firebird dialect adds CHAR, VARCHAR types which
+ accept a "charset" flag, to support Firebird
+ "CHARACTER SET" clause.
+
+ .. change::
+ :tags: declarative
+ :tickets: 1805, 1796, 1751
+
+ Added support for @classproperty to provide
+ any kind of schema/mapping construct from a
+ declarative mixin, including columns with foreign
+ keys, relationships, column_property, deferred.
+ This solves all such issues on declarative mixins.
+ An error is raised if any MapperProperty subclass
+ is specified on a mixin without using @classproperty.
+
+ .. change::
+ :tags: declarative
+ :tickets: 1821
+
+ a mixin class can now define a column that matches
+ one which is present on a __table__ defined on a
+ subclass. It cannot, however, define one that is
+ not present in the __table__, and the error message
+ here now works.
+
+ .. change::
+ :tags: extension, compiler
+ :tickets: 1838
+
+ The 'default' compiler is automatically copied over
+ when overriding the compilation of a built in
+ clause construct, so no KeyError is raised if the
+ user-defined compiler is specific to certain
+ backends and compilation for a different backend
+ is invoked.
+
+ .. change::
+ :tags: documentation
+ :tickets: 1820
+
+ Added documentation for the Inspector.
+
+ .. change::
+ :tags: documentation
+ :tickets: 1830
+
+ Fixed @memoized_property and @memoized_instancemethod
+ decorators so that Sphinx documentation picks up
+ these attributes and methods, such as
+ ResultProxy.inserted_primary_key.
+
+.. changelog::
+ :version: 0.6.1
+ :released: Mon May 31 2010
+
+ .. change::
+ :tags: orm
+ :tickets: 1782
+
+ Fixed regression introduced in 0.6.0 involving improper
+ history accounting on mutable attributes.
+
+ .. change::
+ :tags: orm
+ :tickets: 1807
+
+ Fixed regression introduced in 0.6.0 unit of work refactor
+ that broke updates for bi-directional relationship()
+ with post_update=True.
+
+ .. change::
+ :tags: orm
+ :tickets: 1789
+
+ session.merge() will not expire attributes on the returned
+ instance if that instance is "pending".
+
+ .. change::
+ :tags: orm
+ :tickets: 1802
+
+ fixed __setstate__ method of CollectionAdapter to not
+ fail during deserialize where parent InstanceState not
+ yet unserialized.
+
+ .. change::
+ :tags: orm
+ :tickets: 1797
+
+ Added internal warning in case an instance without a
+ full PK happened to be expired and then was asked
+ to refresh.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Added more aggressive caching to the mapper's usage of
+ UPDATE, INSERT, and DELETE expressions. Assuming the
+ statement has no per-object SQL expressions attached,
+ the expression objects are cached by the mapper after
+ the first create, and their compiled form is stored
+ persistently in a cache dictionary for the duration of
+ the related Engine. The cache is an LRUCache for the
+ rare case that a mapper receives an extremely
+ high number of different column patterns as UPDATEs.
+
+ .. change::
+ :tags: sql
+ :tickets: 1793
+
+ expr.in_() now accepts a text() construct as the argument.
+ Grouping parenthesis are added automatically, i.e. usage
+ is like `col.in_(text("select id from table"))`.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Columns of _Binary type (i.e. LargeBinary, BLOB, etc.)
+ will coerce a "basestring" on the right side into a
+ _Binary as well so that required DBAPI processing
+ takes place.
+
+ .. change::
+ :tags: sql
+ :tickets: 1801
+
+ Added table.add_is_dependent_on(othertable), allows manual
+ placement of dependency rules between two Table objects
+ for use within create_all(), drop_all(), sorted_tables.
+
+ .. change::
+ :tags: sql
+ :tickets: 1778
+
+ Fixed bug that prevented implicit RETURNING from functioning
+ properly with composite primary key that contained zeroes.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Fixed errant space character when generating ADD CONSTRAINT
+ for a named UNIQUE constraint.
+
+ .. change::
+ :tags: sql
+ :tickets: 1571
+
+ Fixed "table" argument on constructor of ForeginKeyConstraint
+
+ .. change::
+ :tags: sql
+ :tickets: 1786
+
+ Fixed bug in connection pool cursor wrapper whereby if a
+ cursor threw an exception on close(), the logging of the
+ message would fail.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ the _make_proxy() method of ColumnClause and Column now use
+ self.__class__ to determine the class of object to be returned
+ instead of hardcoding to ColumnClause/Column, making it slightly
+ easier to produce specific subclasses of these which work in
+ alias/subquery situations.
+
+ .. change::
+ :tags: sql
+ :tickets: 1798
+
+ func.XXX() doesn't inadvertently resolve to non-Function
+ classes (e.g. fixes func.text()).
+
+ .. change::
+ :tags: engines
+ :tickets: 1781
+
+ Fixed building the C extensions on Python 2.4.
+
+ .. change::
+ :tags: engines
+ :tickets:
+
+ Pool classes will reuse the same "pool_logging_name" setting
+ after a dispose() occurs.
+
+ .. change::
+ :tags: engines
+ :tickets:
+
+ Engine gains an "execution_options" argument and
+ update_execution_options() method, which will apply to
+ all connections generated by this engine.
+
+ .. change::
+ :tags: mysql
+ :tickets: 1794
+
+ func.sysdate() emits "SYSDATE()", i.e. with the ending
+ parenthesis, on MySQL.
+
+ .. change::
+ :tags: sqlite
+ :tickets: 1812
+
+ Fixed concatenation of constraints when "PRIMARY KEY"
+ constraint gets moved to column level due to SQLite
+ AUTOINCREMENT keyword being rendered.
+
+ .. change::
+ :tags: oracle
+ :tickets: 1775
+
+ Added a check for cx_oracle versions lower than version 5,
+ in which case the incompatible "output type handler" won't
+ be used. This will impact decimal accuracy and some
+ unicode handling issues.
+
+ .. change::
+ :tags: oracle
+ :tickets: 1790
+
+ Fixed use_ansi=False mode, which was producing broken
+ WHERE clauses in pretty much all cases.
+
+ .. change::
+ :tags: oracle
+ :tickets: 1808
+
+ Re-established support for Oracle 8 with cx_oracle,
+ including that use_ansi is set to False automatically,
+ NVARCHAR2 and NCLOB are not rendered for Unicode,
+ "native unicode" check doesn't fail, cx_oracle
+ "native unicode" mode is disabled, VARCHAR() is emitted
+ with bytes count instead of char count.
+
+ .. change::
+ :tags: oracle
+ :tickets: 1670
+
+ oracle_xe 5 doesn't accept a Python unicode object in
+ its connect string in normal Python 2.x mode - so we coerce
+ to str() directly. non-ascii characters aren't supported
+ in connect strings here since we don't know what encoding
+ we could use.
+
+ .. change::
+ :tags: oracle
+ :tickets: 1815
+
+ FOR UPDATE is emitted in the syntactically correct position
+ when limit/offset is used, i.e. the ROWNUM subquery.
+ However, Oracle can't really handle FOR UPDATE with ORDER BY
+ or with subqueries, so its still not very usable, but at
+ least SQLA gets the SQL past the Oracle parser.
+
+ .. change::
+ :tags: firebird
+ :tickets: 1521
+
+ Added a label to the query used within has_table() and
+ has_sequence() to work with older versions of Firebird
+ that don't provide labels for result columns.
+
+ .. change::
+ :tags: firebird
+ :tickets: 1779
+
+ Added integer coercion to the "type_conv" attribute when
+ passed via query string, so that it is properly interpreted
+ by Kinterbasdb.
+
+ .. change::
+ :tags: firebird
+ :tickets: 1646
+
+ Added 'connection shutdown' to the list of exception strings
+ which indicate a dropped connection.
+
+ .. change::
+ :tags: sqlsoup
+ :tickets: 1783
+
+ the SqlSoup constructor accepts a `base` argument which specifies
+ the base class to use for mapped classes, the default being
+ `object`.
+
+.. changelog::
+ :version: 0.6.0
+ :released: Sun Apr 18 2010
+
+ .. change::
+ :tags: orm
+ :tickets: 1742, 1081
+
+ Unit of work internals have been rewritten. Units of work
+ with large numbers of objects interdependent objects
+ can now be flushed without recursion overflows
+ as there is no longer reliance upon recursive calls. The number of internal structures now stays
+ constant for a particular session state, regardless of
+ how many relationships are present on mappings. The flow
+ of events now corresponds to a linear list of steps,
+ generated by the mappers and relationships based on actual
+ work to be done, filtered through a single topological sort
+ for correct ordering. Flush actions are assembled using
+ far fewer steps and less memory.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Along with the UOW rewrite, this also removes an issue
+ introduced in 0.6beta3 regarding topological cycle detection
+ for units of work with long dependency cycles. We now use
+ an algorithm written by Guido (thanks Guido!).
+
+ .. change::
+ :tags: orm
+ :tickets: 1764
+
+ one-to-many relationships now maintain a list of positive
+ parent-child associations within the flush, preventing
+ previous parents marked as deleted from cascading a
+ delete or NULL foreign key set on those child objects,
+ despite the end-user not removing the child from the old
+ association.
+
+ .. change::
+ :tags: orm
+ :tickets: 1495
+
+ A collection lazy load will switch off default
+ eagerloading on the reverse many-to-one side, since
+ that loading is by definition unnecessary.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Session.refresh() now does an equivalent expire()
+ on the given instance first, so that the "refresh-expire"
+ cascade is propagated. Previously, refresh() was
+ not affected in any way by the presence of "refresh-expire"
+ cascade. This is a change in behavior versus that
+ of 0.6beta2, where the "lockmode" flag passed to refresh()
+ would cause a version check to occur. Since the instance
+ is first expired, refresh() always upgrades the object
+ to the most recent version.
+
+ .. change::
+ :tags: orm
+ :tickets: 1754
+
+ The 'refresh-expire' cascade, when reaching a pending object,
+ will expunge the object if the cascade also includes
+ "delete-orphan", or will simply detach it otherwise.
+
+ .. change::
+ :tags: orm
+ :tickets: 1756
+
+ id(obj) is no longer used internally within topological.py,
+ as the sorting functions now require hashable objects
+ only.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ The ORM will set the docstring of all generated descriptors
+ to None by default. This can be overridden using 'doc'
+ (or if using Sphinx, attribute docstrings work too).
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Added kw argument 'doc' to all mapper property callables
+ as well as Column(). Will assemble the string 'doc' as
+ the '__doc__' attribute on the descriptor.
+
+ .. change::
+ :tags: orm
+ :tickets: 1761
+
+ Usage of version_id_col on a backend that supports
+ cursor.rowcount for execute() but not executemany() now works
+ when a delete is issued (already worked for saves, since those
+ don't use executemany()). For a backend that doesn't support
+ cursor.rowcount at all, a warning is emitted the same
+ as with saves.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ The ORM now short-term caches the "compiled" form of
+ insert() and update() constructs when flushing lists of
+ objects of all the same class, thereby avoiding redundant
+ compilation per individual INSERT/UPDATE within an
+ individual flush() call.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ internal getattr(), setattr(), getcommitted() methods
+ on ColumnProperty, CompositeProperty, RelationshipProperty
+ have been underscored (i.e. are private), signature has
+ changed.
+
+ .. change::
+ :tags: engines
+ :tickets: 1757
+
+ The C extension now also works with DBAPIs which use custom
+ sequences as row (and not only tuples).
+
+ .. change::
+ :tags: sql
+ :tickets: 1755
+
+ Restored some bind-labeling logic from 0.5 which ensures
+ that tables with column names that overlap another column
+ of the form "<tablename>_<columnname>" won't produce
+ errors if column._label is used as a bind name during
+ an UPDATE. Test coverage which wasn't present in 0.5
+ has been added.
+
+ .. change::
+ :tags: sql
+ :tickets: 1729
+
+ somejoin.select(fold_equivalents=True) is no longer
+ deprecated, and will eventually be rolled into a more
+ comprehensive version of the feature for.
+
+ .. change::
+ :tags: sql
+ :tickets: 1759
+
+ the Numeric type raises an *enormous* warning when expected
+ to convert floats to Decimal from a DBAPI that returns floats.
+ This includes SQLite, Sybase, MS-SQL.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Fixed an error in expression typing which caused an endless
+ loop for expressions with two NULL types.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Fixed bug in execution_options() feature whereby the existing
+ Transaction and other state information from the parent
+ connection would not be propagated to the sub-connection.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Added new 'compiled_cache' execution option. A dictionary
+ where Compiled objects will be cached when the Connection
+ compiles a clause expression into a dialect- and parameter-
+ specific Compiled object. It is the user's responsibility to
+ manage the size of this dictionary, which will have keys
+ corresponding to the dialect, clause element, the column
+ names within the VALUES or SET clause of an INSERT or UPDATE,
+ as well as the "batch" mode for an INSERT or UPDATE statement.
+
+ .. change::
+ :tags: sql
+ :tickets: 1769
+
+ Added get_pk_constraint() to reflection.Inspector, similar
+ to get_primary_keys() except returns a dict that includes the
+ name of the constraint, for supported backends (PG so far).
+
+ .. change::
+ :tags: sql
+ :tickets: 1771
+
+ Table.create() and Table.drop() no longer apply metadata-
+ level create/drop events.
+
+ .. change::
+ :tags: ext
+ :tickets:
+
+ the compiler extension now allows @compiles decorators
+ on base classes that extend to child classes, @compiles
+ decorators on child classes that aren't broken by a
+ @compiles decorator on the base class.
+
+ .. change::
+ :tags: ext
+ :tickets:
+
+ Declarative will raise an informative error message
+ if a non-mapped class attribute is referenced in the
+ string-based relationship() arguments.
+
+ .. change::
+ :tags: ext
+ :tickets:
+
+ Further reworked the "mixin" logic in declarative to
+ additionally allow __mapper_args__ as a @classproperty
+ on a mixin, such as to dynamically assign polymorphic_identity.
+
+ .. change::
+ :tags: postgresql
+ :tickets: 1071
+
+ Postgresql now reflects sequence names associated with
+ SERIAL columns correctly, after the name of of the sequence
+ has been changed. Thanks to Kumar McMillan for the patch.
+
+ .. change::
+ :tags: postgresql
+ :tickets:
+
+ Repaired missing import in psycopg2._PGNumeric type when
+ unknown numeric is received.
+
+ .. change::
+ :tags: postgresql
+ :tickets:
+
+ psycopg2/pg8000 dialects now aware of REAL[], FLOAT[],
+ DOUBLE_PRECISION[], NUMERIC[] return types without
+ raising an exception.
+
+ .. change::
+ :tags: postgresql
+ :tickets: 1769
+
+ Postgresql reflects the name of primary key constraints,
+ if one exists.
+
+ .. change::
+ :tags: oracle
+ :tickets:
+
+ Now using cx_oracle output converters so that the
+ DBAPI returns natively the kinds of values we prefer:
+
+ .. change::
+ :tags: oracle
+ :tickets: 1759
+
+ NUMBER values with positive precision + scale convert
+ to cx_oracle.STRING and then to Decimal. This
+ allows perfect precision for the Numeric type when
+ using cx_oracle.
+
+ .. change::
+ :tags: oracle
+ :tickets:
+
+ STRING/FIXED_CHAR now convert to unicode natively.
+ SQLAlchemy's String types then don't need to
+ apply any kind of conversions.
+
+ .. change::
+ :tags: firebird
+ :tickets:
+
+ The functionality of result.rowcount can be disabled on a
+ per-engine basis by setting 'enable_rowcount=False'
+ on create_engine(). Normally, cursor.rowcount is called
+ after any UPDATE or DELETE statement unconditionally,
+ because the cursor is then closed and Firebird requires
+ an open cursor in order to get a rowcount. This
+ call is slightly expensive however so it can be disabled.
+ To re-enable on a per-execution basis, the
+ 'enable_rowcount=True' execution option may be used.
+
+ .. change::
+ :tags: examples
+ :tickets:
+
+ Updated attribute_shard.py example to use a more robust
+ method of searching a Query for binary expressions which
+ compare columns against literal values.
+
+.. changelog::
+ :version: 0.6beta3
+ :released: Sun Mar 28 2010
+
+ .. change::
+ :tags: orm
+ :tickets: 1675
+
+ Major feature: Added new "subquery" loading capability to
+ relationship(). This is an eager loading option which
+ generates a second SELECT for each collection represented
+ in a query, across all parents at once. The query
+ re-issues the original end-user query wrapped in a subquery,
+ applies joins out to the target collection, and loads
+ all those collections fully in one result, similar to
+ "joined" eager loading but using all inner joins and not
+ re-fetching full parent rows repeatedly (as most DBAPIs seem
+ to do, even if columns are skipped). Subquery loading is
+ available at mapper config level using "lazy='subquery'" and
+ at the query options level using "subqueryload(props..)",
+ "subqueryload_all(props...)".
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ To accomodate the fact that there are now two kinds of eager
+ loading available, the new names for eagerload() and
+ eagerload_all() are joinedload() and joinedload_all(). The
+ old names will remain as synonyms for the foreseeable future.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ The "lazy" flag on the relationship() function now accepts
+ a string argument for all kinds of loading: "select", "joined",
+ "subquery", "noload" and "dynamic", where the default is now
+ "select". The old values of True/
+ False/None still retain their usual meanings and will remain
+ as synonyms for the foreseeable future.
+
+ .. change::
+ :tags: orm
+ :tickets: 921
+
+ Added with_hint() method to Query() construct. This calls
+ directly down to select().with_hint() and also accepts
+ entities as well as tables and aliases. See with_hint() in the
+ SQL section below.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Fixed bug in Query whereby calling q.join(prop).from_self(...).
+ join(prop) would fail to render the second join outside the
+ subquery, when joining on the same criterion as was on the
+ inside.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Fixed bug in Query whereby the usage of aliased() constructs
+ would fail if the underlying table (but not the actual alias)
+ were referenced inside the subquery generated by
+ q.from_self() or q.select_from().
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Fixed bug which affected all eagerload() and similar options
+ such that "remote" eager loads, i.e. eagerloads off of a lazy
+ load such as query(A).options(eagerload(A.b, B.c))
+ wouldn't eagerload anything, but using eagerload("b.c") would
+ work fine.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Query gains an add_columns(*columns) method which is a multi-
+ version of add_column(col). add_column(col) is future
+ deprecated.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Query.join() will detect if the end result will be
+ "FROM A JOIN A", and will raise an error if so.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Query.join(Cls.propname, from_joinpoint=True) will check more
+ carefully that "Cls" is compatible with the current joinpoint,
+ and act the same way as Query.join("propname", from_joinpoint=True)
+ in that regard.
+
+ .. change::
+ :tags: sql
+ :tickets: 921
+
+ Added with_hint() method to select() construct. Specify
+ a table/alias, hint text, and optional dialect name, and
+ "hints" will be rendered in the appropriate place in the
+ statement. Works for Oracle, Sybase, MySQL.
+
+ .. change::
+ :tags: sql
+ :tickets: 1747
+
+ Fixed bug introduced in 0.6beta2 where column labels would
+ render inside of column expressions already assigned a label.
+
+ .. change::
+ :tags: postgresql
+ :tickets: 877
+
+ The psycopg2 dialect will log NOTICE messages via the
+ "sqlalchemy.dialects.postgresql" logger name.
+
+ .. change::
+ :tags: postgresql
+ :tickets: 997
+
+ the TIME and TIMESTAMP types are now availble from the
+ postgresql dialect directly, which add the PG-specific
+ argument 'precision' to both. 'precision' and
+ 'timezone' are correctly reflected for both TIME and
+ TIMEZONE types.
+
+ .. change::
+ :tags: mysql
+ :tickets: 1752
+
+ No longer guessing that TINYINT(1) should be BOOLEAN
+ when reflecting - TINYINT(1) is returned. Use Boolean/
+ BOOLEAN in table definition to get boolean conversion
+ behavior.
+
+ .. change::
+ :tags: oracle
+ :tickets: 1744
+
+ The Oracle dialect will issue VARCHAR type definitions
+ using character counts, i.e. VARCHAR2(50 CHAR), so that
+ the column is sized in terms of characters and not bytes.
+ Column reflection of character types will also use
+ ALL_TAB_COLUMNS.CHAR_LENGTH instead of
+ ALL_TAB_COLUMNS.DATA_LENGTH. Both of these behaviors take
+ effect when the server version is 9 or higher - for
+ version 8, the old behaviors are used.
+
+ .. change::
+ :tags: declarative
+ :tickets: 1746
+
+ Using a mixin won't break if the mixin implements an
+ unpredictable __getattribute__(), i.e. Zope interfaces.
+
+ .. change::
+ :tags: declarative
+ :tickets: 1749
+
+ Using @classdecorator and similar on mixins to define
+ __tablename__, __table_args__, etc. now works if
+ the method references attributes on the ultimate
+ subclass.
+
+ .. change::
+ :tags: declarative
+ :tickets: 1751
+
+ relationships and columns with foreign keys aren't
+ allowed on declarative mixins, sorry.
+
+ .. change::
+ :tags: ext
+ :tickets:
+
+ The sqlalchemy.orm.shard module now becomes an extension,
+ sqlalchemy.ext.horizontal_shard. The old import
+ works with a deprecation warning.
+
+.. changelog::
+ :version: 0.6beta2
+ :released: Sat Mar 20 2010
+
+ .. change::
+ :tags: py3k
+ :tickets:
+
+ Improved the installation/test setup regarding Python 3,
+ now that Distribute runs on Py3k. distribute_setup.py
+ is now included. See README.py3k for Python 3 installation/
+ testing instructions.
+
+ .. change::
+ :tags: orm
+ :tickets: 1740
+
+ The official name for the relation() function is now
+ relationship(), to eliminate confusion over the relational
+ algebra term. relation() however will remain available
+ in equal capacity for the foreseeable future.
+
+ .. change::
+ :tags: orm
+ :tickets: 1692
+
+ Added "version_id_generator" argument to Mapper, this is a
+ callable that, given the current value of the "version_id_col",
+ returns the next version number. Can be used for alternate
+ versioning schemes such as uuid, timestamps.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ added "lockmode" kw argument to Session.refresh(), will
+ pass through the string value to Query the same as
+ in with_lockmode(), will also do version check for a
+ version_id_col-enabled mapping.
+
+ .. change::
+ :tags: orm
+ :tickets: 1188
+
+ Fixed bug whereby calling query(A).join(A.bs).add_entity(B)
+ in a joined inheritance scenario would double-add B as a
+ target and produce an invalid query.
+
+ .. change::
+ :tags: orm
+ :tickets: 1674
+
+ Fixed bug in session.rollback() which involved not removing
+ formerly "pending" objects from the session before
+ re-integrating "deleted" objects, typically occured with
+ natural primary keys. If there was a primary key conflict
+ between them, the attach of the deleted would fail
+ internally. The formerly "pending" objects are now expunged
+ first.
+
+ .. change::
+ :tags: orm
+ :tickets: 1719
+
+ Removed a lot of logging that nobody really cares about,
+ logging that remains will respond to live changes in the
+ log level. No significant overhead is added.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Fixed bug in session.merge() which prevented dict-like
+ collections from merging.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ session.merge() works with relations that specifically
+ don't include "merge" in their cascade options - the target
+ is ignored completely.
+
+ .. change::
+ :tags: orm
+ :tickets: 1681
+
+ session.merge() will not expire existing scalar attributes
+ on an existing target if the target has a value for that
+ attribute, even if the incoming merged doesn't have
+ a value for the attribute. This prevents unnecessary loads
+ on existing items. Will still mark the attr as expired
+ if the destination doesn't have the attr, though, which
+ fulfills some contracts of deferred cols.
+
+ .. change::
+ :tags: orm
+ :tickets: 1680
+
+ The "allow_null_pks" flag is now called "allow_partial_pks",
+ defaults to True, acts like it did in 0.5 again. Except,
+ it also is implemented within merge() such that a SELECT
+ won't be issued for an incoming instance with partially
+ NULL primary key if the flag is False.
+
+ .. change::
+ :tags: orm
+ :tickets: 1737
+
+ Fixed bug in 0.6-reworked "many-to-one" optimizations
+ such that a many-to-one that is against a non-primary key
+ column on the remote table (i.e. foreign key against a
+ UNIQUE column) will pull the "old" value in from the
+ database during a change, since if it's in the session
+ we will need it for proper history/backref accounting,
+ and we can't pull from the local identity map on a
+ non-primary key column.
+
+ .. change::
+ :tags: orm
+ :tickets: 1731
+
+ fixed internal error which would occur if calling has()
+ or similar complex expression on a single-table inheritance
+ relation().
+
+ .. change::
+ :tags: orm
+ :tickets: 1688
+
+ query.one() no longer applies LIMIT to the query, this to
+ ensure that it fully counts all object identities present
+ in the result, even in the case where joins may conceal
+ multiple identities for two or more rows. As a bonus,
+ one() can now also be called with a query that issued
+ from_statement() to start with since it no longer modifies
+ the query.
+
+ .. change::
+ :tags: orm
+ :tickets: 1727
+
+ query.get() now returns None if queried for an identifier
+ that is present in the identity map with a different class
+ than the one requested, i.e. when using polymorphic loading.
+
+ .. change::
+ :tags: orm
+ :tickets: 1706
+
+ A major fix in query.join(), when the "on" clause is an
+ attribute of an aliased() construct, but there is already
+ an existing join made out to a compatible target, query properly
+ joins to the right aliased() construct instead of sticking
+ onto the right side of the existing join.
+
+ .. change::
+ :tags: orm
+ :tickets: 1362
+
+ Slight improvement to the fix for to not issue
+ needless updates of the primary key column during a so-called
+ "row switch" operation, i.e. add + delete of two objects
+ with the same PK.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Now uses sqlalchemy.orm.exc.DetachedInstanceError when an
+ attribute load or refresh action fails due to object
+ being detached from any Session. UnboundExecutionError
+ is specific to engines bound to sessions and statements.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Query called in the context of an expression will render
+ disambiguating labels in all cases. Note that this does
+ not apply to the existing .statement and .subquery()
+ accessor/method, which still honors the .with_labels()
+ setting that defaults to False.
+
+ .. change::
+ :tags: orm
+ :tickets: 1676
+
+ Query.union() retains disambiguating labels within the
+ returned statement, thus avoiding various SQL composition
+ errors which can result from column name conflicts.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Fixed bug in attribute history that inadvertently invoked
+ __eq__ on mapped instances.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Some internal streamlining of object loading grants a
+ small speedup for large results, estimates are around
+ 10-15%. Gave the "state" internals a good solid
+ cleanup with less complexity, datamembers,
+ method calls, blank dictionary creates.
+
+ .. change::
+ :tags: orm
+ :tickets: 1689
+
+ Documentation clarification for query.delete()
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Fixed cascade bug in many-to-one relation() when attribute
+ was set to None, introduced in r6711 (cascade deleted
+ items into session during add()).
+
+ .. change::
+ :tags: orm
+ :tickets: 1736
+
+ Calling query.order_by() or query.distinct() before calling
+ query.select_from(), query.with_polymorphic(), or
+ query.from_statement() raises an exception now instead of
+ silently dropping those criterion.
+
+ .. change::
+ :tags: orm
+ :tickets: 1735
+
+ query.scalar() now raises an exception if more than one
+ row is returned. All other behavior remains the same.
+
+ .. change::
+ :tags: orm
+ :tickets: 1692
+
+ Fixed bug which caused "row switch" logic, that is an
+ INSERT and DELETE replaced by an UPDATE, to fail when
+ version_id_col was in use.
+
+ .. change::
+ :tags: sql
+ :tickets: 1714
+
+ join() will now simulate a NATURAL JOIN by default. Meaning,
+ if the left side is a join, it will attempt to join the right
+ side to the rightmost side of the left first, and not raise
+ any exceptions about ambiguous join conditions if successful
+ even if there are further join targets across the rest of
+ the left.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ The most common result processors conversion function were
+ moved to the new "processors" module. Dialect authors are
+ encouraged to use those functions whenever they correspond
+ to their needs instead of implementing custom ones.
+
+ .. change::
+ :tags: sql
+ :tickets: 1694, 1698
+
+ SchemaType and subclasses Boolean, Enum are now serializable,
+ including their ddl listener and other event callables.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Some platforms will now interpret certain literal values
+ as non-bind parameters, rendered literally into the SQL
+ statement. This to support strict SQL-92 rules that are
+ enforced by some platforms including MS-SQL and Sybase.
+ In this model, bind parameters aren't allowed in the
+ columns clause of a SELECT, nor are certain ambiguous
+ expressions like "?=?". When this mode is enabled, the base
+ compiler will render the binds as inline literals, but only across
+ strings and numeric values. Other types such as dates
+ will raise an error, unless the dialect subclass defines
+ a literal rendering function for those. The bind parameter
+ must have an embedded literal value already or an error
+ is raised (i.e. won't work with straight bindparam('x')).
+ Dialects can also expand upon the areas where binds are not
+ accepted, such as within argument lists of functions
+ (which don't work on MS-SQL when native SQL binding is used).
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Added "unicode_errors" parameter to String, Unicode, etc.
+ Behaves like the 'errors' keyword argument to
+ the standard library's string.decode() functions. This flag
+ requires that `convert_unicode` is set to `"force"` - otherwise,
+ SQLAlchemy is not guaranteed to handle the task of unicode
+ conversion. Note that this flag adds significant performance
+ overhead to row-fetching operations for backends that already
+ return unicode objects natively (which most DBAPIs do). This
+ flag should only be used as an absolute last resort for reading
+ strings from a column with varied or corrupted encodings,
+ which only applies to databases that accept invalid encodings
+ in the first place (i.e. MySQL. *not* PG, Sqlite, etc.)
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Added math negation operator support, -x.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ FunctionElement subclasses are now directly executable the
+ same way any func.foo() construct is, with automatic
+ SELECT being applied when passed to execute().
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ The "type" and "bind" keyword arguments of a func.foo()
+ construct are now local to "func." constructs and are
+ not part of the FunctionElement base class, allowing
+ a "type" to be handled in a custom constructor or
+ class-level variable.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Restored the keys() method to ResultProxy.
+
+ .. change::
+ :tags: sql
+ :tickets: 1647, 1683
+
+ The type/expression system now does a more complete job
+ of determining the return type from an expression
+ as well as the adaptation of the Python operator into
+ a SQL operator, based on the full left/right/operator
+ of the given expression. In particular
+ the date/time/interval system created for Postgresql
+ EXTRACT in has now been generalized into
+ the type system. The previous behavior which often
+ occured of an expression "column + literal" forcing
+ the type of "literal" to be the same as that of "column"
+ will now usually not occur - the type of
+ "literal" is first derived from the Python type of the
+ literal, assuming standard native Python types + date
+ types, before falling back to that of the known type
+ on the other side of the expression. If the
+ "fallback" type is compatible (i.e. CHAR from String),
+ the literal side will use that. TypeDecorator
+ types override this by default to coerce the "literal"
+ side unconditionally, which can be changed by implementing
+ the coerce_compared_value() method. Also part of.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Made sqlalchemy.sql.expressions.Executable part of public
+ API, used for any expression construct that can be sent to
+ execute(). FunctionElement now inherits Executable so that
+ it gains execution_options(), which are also propagated
+ to the select() that's generated within execute().
+ Executable in turn subclasses _Generative which marks
+ any ClauseElement that supports the @_generative
+ decorator - these may also become "public" for the benefit
+ of the compiler extension at some point.
+
+ .. change::
+ :tags: sql
+ :tickets: 1579
+
+ A change to the solution for - an end-user
+ defined bind parameter name that directly conflicts with
+ a column-named bind generated directly from the SET or
+ VALUES clause of an update/insert generates a compile error.
+ This reduces call counts and eliminates some cases where
+ undesirable name conflicts could still occur.
+
+ .. change::
+ :tags: sql
+ :tickets: 1705
+
+ Column() requires a type if it has no foreign keys (this is
+ not new). An error is now raised if a Column() has no type
+ and no foreign keys.
+
+ .. change::
+ :tags: sql
+ :tickets: 1717
+
+ the "scale" argument of the Numeric() type is honored when
+ coercing a returned floating point value into a string
+ on its way to Decimal - this allows accuracy to function
+ on SQLite, MySQL.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ the copy() method of Column now copies over uninitialized
+ "on table attach" events. Helps with the new declarative
+ "mixin" capability.
+
+ .. change::
+ :tags: engines
+ :tickets:
+
+ Added an optional C extension to speed up the sql layer by
+ reimplementing RowProxy and the most common result processors.
+ The actual speedups will depend heavily on your DBAPI and
+ the mix of datatypes used in your tables, and can vary from
+ a 30% improvement to more than 200%. It also provides a modest
+ (~15-20%) indirect improvement to ORM speed for large queries.
+ Note that it is *not* built/installed by default.
+ See README for installation instructions.
+
+ .. change::
+ :tags: engines
+ :tickets:
+
+ the execution sequence pulls all rowcount/last inserted ID
+ info from the cursor before commit() is called on the
+ DBAPI connection in an "autocommit" scenario. This helps
+ mxodbc with rowcount and is probably a good idea overall.
+
+ .. change::
+ :tags: engines
+ :tickets: 1719
+
+ Opened up logging a bit such that isEnabledFor() is called
+ more often, so that changes to the log level for engine/pool
+ will be reflected on next connect. This adds a small
+ amount of method call overhead. It's negligible and will make
+ life a lot easier for all those situations when logging
+ just happens to be configured after create_engine() is called.
+
+ .. change::
+ :tags: engines
+ :tickets:
+
+ The assert_unicode flag is deprecated. SQLAlchemy will raise
+ a warning in all cases where it is asked to encode a non-unicode
+ Python string, as well as when a Unicode or UnicodeType type
+ is explicitly passed a bytestring. The String type will do nothing
+ for DBAPIs that already accept Python unicode objects.
+
+ .. change::
+ :tags: engines
+ :tickets:
+
+ Bind parameters are sent as a tuple instead of a list. Some
+ backend drivers will not accept bind parameters as a list.
+
+ .. change::
+ :tags: engines
+ :tickets:
+
+ threadlocal engine wasn't properly closing the connection
+ upon close() - fixed that.
+
+ .. change::
+ :tags: engines
+ :tickets:
+
+ Transaction object doesn't rollback or commit if it isn't
+ "active", allows more accurate nesting of begin/rollback/commit.
+
+ .. change::
+ :tags: engines
+ :tickets:
+
+ Python unicode objects as binds result in the Unicode type,
+ not string, thus eliminating a certain class of unicode errors
+ on drivers that don't support unicode binds.
+
+ .. change::
+ :tags: engines
+ :tickets: 1555
+
+ Added "logging_name" argument to create_engine(), Pool() constructor
+ as well as "pool_logging_name" argument to create_engine() which
+ filters down to that of Pool. Issues the given string name
+ within the "name" field of logging messages instead of the default
+ hex identifier string.
+
+ .. change::
+ :tags: engines
+ :tickets:
+
+ The visit_pool() method of Dialect is removed, and replaced with
+ connect(). This method returns a callable which receives
+ the raw DBAPI connection after each one is created. The callable
+ is assembled into a first_connect/connect pool listener by the
+ connection strategy if non-None. Provides a simpler interface
+ for dialects.
+
+ .. change::
+ :tags: engines
+ :tickets: 1728
+
+ StaticPool now initializes, disposes and recreates without
+ opening a new connection - the connection is only opened when
+ first requested. dispose() also works on AssertionPool now.
+
+ .. change::
+ :tags: ticket: 1673, metadata
+ :tickets:
+
+ Added the ability to strip schema information when using
+ "tometadata" by passing "schema=None" as an argument. If schema
+ is not specified then the table's schema is retained.
+
+ .. change::
+ :tags: declarative
+ :tickets:
+
+ DeclarativeMeta exclusively uses cls.__dict__ (not dict_)
+ as the source of class information; _as_declarative exclusively
+ uses the dict_ passed to it as the source of class information
+ (which when using DeclarativeMeta is cls.__dict__). This should
+ in theory make it easier for custom metaclasses to modify
+ the state passed into _as_declarative.
+
+ .. change::
+ :tags: declarative
+ :tickets: 1707
+
+ declarative now accepts mixin classes directly, as a means
+ to provide common functional and column-based elements on
+ all subclasses, as well as a means to propagate a fixed
+ set of __table_args__ or __mapper_args__ to subclasses.
+ For custom combinations of __table_args__/__mapper_args__ from
+ an inherited mixin to local, descriptors can now be used.
+ New details are all up in the Declarative documentation.
+ Thanks to Chris Withers for putting up with my strife
+ on this.
+
+ .. change::
+ :tags: declarative
+ :tickets: 1393
+
+ the __mapper_args__ dict is copied when propagating to a subclass,
+ and is taken straight off the class __dict__ to avoid any
+ propagation from the parent. mapper inheritance already
+ propagates the things you want from the parent mapper.
+
+ .. change::
+ :tags: declarative
+ :tickets: 1732
+
+ An exception is raised when a single-table subclass specifies
+ a column that is already present on the base class.
+
+ .. change::
+ :tags: mysql
+ :tickets: 1655
+
+ Fixed reflection bug whereby when COLLATE was present,
+ nullable flag and server defaults would not be reflected.
+
+ .. change::
+ :tags: mysql
+ :tickets:
+
+ Fixed reflection of TINYINT(1) "boolean" columns defined with
+ integer flags like UNSIGNED.
+
+ .. change::
+ :tags: mysql
+ :tickets: 1668
+
+ Further fixes for the mysql-connector dialect.
+
+ .. change::
+ :tags: mysql
+ :tickets: 1496
+
+ Composite PK table on InnoDB where the "autoincrement" column
+ isn't first will emit an explicit "KEY" phrase within
+ CREATE TABLE thereby avoiding errors.
+
+ .. change::
+ :tags: mysql
+ :tickets: 1634
+
+ Added reflection/create table support for a wide range
+ of MySQL keywords.
+
+ .. change::
+ :tags: mysql
+ :tickets: 1580
+
+ Fixed import error which could occur reflecting tables on
+ a Windows host
+
+ .. change::
+ :tags: mssql
+ :tickets:
+
+ Re-established support for the pymssql dialect.
+
+ .. change::
+ :tags: mssql
+ :tickets:
+
+ Various fixes for implicit returning, reflection,
+ etc. - the MS-SQL dialects aren't quite complete
+ in 0.6 yet (but are close)
+
+ .. change::
+ :tags: mssql
+ :tickets: 1710
+
+ Added basic support for mxODBC.
+
+ .. change::
+ :tags: mssql
+ :tickets:
+
+ Removed the text_as_varchar option.
+
+ .. change::
+ :tags: oracle
+ :tickets:
+
+ "out" parameters require a type that is supported by
+ cx_oracle. An error will be raised if no cx_oracle
+ type can be found.
+
+ .. change::
+ :tags: oracle
+ :tickets:
+
+ Oracle 'DATE' now does not perform any result processing,
+ as the DATE type in Oracle stores full date+time objects,
+ that's what you'll get. Note that the generic types.Date
+ type *will* still call value.date() on incoming values,
+ however. When reflecting a table, the reflected type
+ will be 'DATE'.
+
+ .. change::
+ :tags: oracle
+ :tickets: 1670
+
+ Added preliminary support for Oracle's WITH_UNICODE
+ mode. At the very least this establishes initial
+ support for cx_Oracle with Python 3. When WITH_UNICODE
+ mode is used in Python 2.xx, a large and scary warning
+ is emitted asking that the user seriously consider
+ the usage of this difficult mode of operation.
+
+ .. change::
+ :tags: oracle
+ :tickets: 1712
+
+ The except_() method now renders as MINUS on Oracle,
+ which is more or less equivalent on that platform.
+
+ .. change::
+ :tags: oracle
+ :tickets: 651
+
+ Added support for rendering and reflecting
+ TIMESTAMP WITH TIME ZONE, i.e. TIMESTAMP(timezone=True).
+
+ .. change::
+ :tags: oracle
+ :tickets:
+
+ Oracle INTERVAL type can now be reflected.
+
+ .. change::
+ :tags: sqlite
+ :tickets: 1685
+
+ Added "native_datetime=True" flag to create_engine().
+ This will cause the DATE and TIMESTAMP types to skip
+ all bind parameter and result row processing, under
+ the assumption that PARSE_DECLTYPES has been enabled
+ on the connection. Note that this is not entirely
+ compatible with the "func.current_date()", which
+ will be returned as a string.
+
+ .. change::
+ :tags: sybase
+ :tickets:
+
+ Implemented a preliminary working dialect for Sybase,
+ with sub-implementations for Python-Sybase as well
+ as Pyodbc. Handles table
+ creates/drops and basic round trip functionality.
+ Does not yet include reflection or comprehensive
+ support of unicode/special expressions/etc.
+
+ .. change::
+ :tags: examples
+ :tickets:
+
+ Changed the beaker cache example a bit to have a separate
+ RelationCache option for lazyload caching. This object
+ does a lookup among any number of potential attributes
+ more efficiently by grouping several into a common structure.
+ Both FromCache and RelationCache are simpler individually.
+
+ .. change::
+ :tags: documentation
+ :tickets: 1700
+
+ Major cleanup work in the docs to link class, function, and
+ method names into the API docs.
+
+.. changelog::
+ :version: 0.6beta1
+ :released: Wed Feb 03 2010
+
+ .. change::
+ :tags: Release, Major
+ :tickets:
+
+ For the full set of feature descriptions, see
+ http://www.sqlalchemy.org/trac/wiki/06Migration .
+ This document is a work in progress.
+
+ .. change::
+ :tags: Release, Major
+ :tickets:
+
+ All bug fixes and feature enhancements from the most
+ recent 0.5 version and below are also included within 0.6.
+
+ .. change::
+ :tags: Release, Major
+ :tickets:
+
+ Platforms targeted now include Python 2.4/2.5/2.6, Python
+ 3.1, Jython2.5.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Changes to query.update() and query.delete():
+ - the 'expire' option on query.update() has been renamed to
+ 'fetch', thus matching that of query.delete().
+ 'expire' is deprecated and issues a warning.
+
+ - query.update() and query.delete() both default to
+ 'evaluate' for the synchronize strategy.
+
+ - the 'synchronize' strategy for update() and delete()
+ raises an error on failure. There is no implicit fallback
+ onto "fetch". Failure of evaluation is based on the
+ structure of criteria, so success/failure is deterministic
+ based on code structure.
+
+ .. change::
+ :tags: orm
+ :tickets: 1186, 1492, 1544
+
+ Enhancements on many-to-one relations:
+ - many-to-one relations now fire off a lazyload in fewer
+ cases, including in most cases will not fetch the "old"
+ value when a new one is replaced.
+
+ - many-to-one relation to a joined-table subclass now uses
+ get() for a simple load (known as the "use_get"
+ condition), i.e. Related->Sub(Base), without the need to
+ redefine the primaryjoin condition in terms of the base
+ table.
+
+ - specifying a foreign key with a declarative column, i.e.
+ ForeignKey(MyRelatedClass.id) doesn't break the "use_get"
+ condition from taking place
+
+ - relation(), eagerload(), and eagerload_all() now feature
+ an option called "innerjoin". Specify `True` or `False` to
+ control whether an eager join is constructed as an INNER
+ or OUTER join. Default is `False` as always. The mapper
+ options will override whichever setting is specified on
+ relation(). Should generally be set for many-to-one, not
+ nullable foreign key relations to allow improved join
+ performance.
+
+ - the behavior of eagerloading such that the main query is
+ wrapped in a subquery when LIMIT/OFFSET are present now
+ makes an exception for the case when all eager loads are
+ many-to-one joins. In those cases, the eager joins are
+ against the parent table directly along with the
+ limit/offset without the extra overhead of a subquery,
+ since a many-to-one join does not add rows to the result.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Enhancements / Changes on Session.merge():
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ the "dont_load=True" flag on Session.merge() is deprecated
+ and is now "load=False".
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Session.merge() is performance optimized, using half the
+ call counts for "load=False" mode compared to 0.5 and
+ significantly fewer SQL queries in the case of collections
+ for "load=True" mode.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ merge() will not issue a needless merge of attributes if the
+ given instance is the same instance which is already present.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ merge() now also merges the "options" associated with a given
+ state, i.e. those passed through query.options() which follow
+ along with an instance, such as options to eagerly- or
+ lazyily- load various attributes. This is essential for
+ the construction of highly integrated caching schemes. This
+ is a subtle behavioral change vs. 0.5.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ A bug was fixed regarding the serialization of the "loader
+ path" present on an instance's state, which is also necessary
+ when combining the usage of merge() with serialized state
+ and associated options that should be preserved.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ The all new merge() is showcased in a new comprehensive
+ example of how to integrate Beaker with SQLAlchemy. See
+ the notes in the "examples" note below.
+
+ .. change::
+ :tags: orm
+ :tickets: 1362
+
+ Primary key values can now be changed on a joined-table inheritance
+ object, and ON UPDATE CASCADE will be taken into account when
+ the flush happens. Set the new "passive_updates" flag to False
+ on mapper() when using SQLite or MySQL/MyISAM.
+
+ .. change::
+ :tags: orm
+ :tickets: 1671
+
+ flush() now detects when a primary key column was updated by
+ an ON UPDATE CASCADE operation from another primary key, and
+ can then locate the row for a subsequent UPDATE on the new PK
+ value. This occurs when a relation() is there to establish
+ the relationship as well as passive_updates=True.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ the "save-update" cascade will now cascade the pending *removed*
+ values from a scalar or collection attribute into the new session
+ during an add() operation. This so that the flush() operation
+ will also delete or modify rows of those disconnected items.
+
+ .. change::
+ :tags: orm
+ :tickets: 1531
+
+ Using a "dynamic" loader with a "secondary" table now produces
+ a query where the "secondary" table is *not* aliased. This
+ allows the secondary Table object to be used in the "order_by"
+ attribute of the relation(), and also allows it to be used
+ in filter criterion against the dynamic relation.
+
+ .. change::
+ :tags: orm
+ :tickets: 1643
+
+ relation() with uselist=False will emit a warning when
+ an eager or lazy load locates more than one valid value for
+ the row. This may be due to primaryjoin/secondaryjoin
+ conditions which aren't appropriate for an eager LEFT OUTER
+ JOIN or for other conditions.
+
+ .. change::
+ :tags: orm
+ :tickets: 1633
+
+ an explicit check occurs when a synonym() is used with
+ map_column=True, when a ColumnProperty (deferred or otherwise)
+ exists separately in the properties dictionary sent to mapper
+ with the same keyname. Instead of silently replacing
+ the existing property (and possible options on that property),
+ an error is raised.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ a "dynamic" loader sets up its query criterion at construction
+ time so that the actual query is returned from non-cloning
+ accessors like "statement".
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ the "named tuple" objects returned when iterating a
+ Query() are now pickleable.
+
+ .. change::
+ :tags: orm
+ :tickets: 1542
+
+ mapping to a select() construct now requires that you
+ make an alias() out of it distinctly. This to eliminate
+ confusion over such issues as
+
+ .. change::
+ :tags: orm
+ :tickets: 1537
+
+ query.join() has been reworked to provide more consistent
+ behavior and more flexibility (includes)
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ query.select_from() accepts multiple clauses to produce
+ multiple comma separated entries within the FROM clause.
+ Useful when selecting from multiple-homed join() clauses.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ query.select_from() also accepts mapped classes, aliased()
+ constructs, and mappers as arguments. In particular this
+ helps when querying from multiple joined-table classes to ensure
+ the full join gets rendered.
+
+ .. change::
+ :tags: orm
+ :tickets: 1135
+
+ query.get() can be used with a mapping to an outer join
+ where one or more of the primary key values are None.
+
+ .. change::
+ :tags: orm
+ :tickets: 1568
+
+ query.from_self(), query.union(), others which do a
+ "SELECT * from (SELECT...)" type of nesting will do
+ a better job translating column expressions within the subquery
+ to the columns clause of the outer query. This is
+ potentially backwards incompatible with 0.5, in that this
+ may break queries with literal expressions that do not have labels
+ applied (i.e. literal('foo'), etc.)
+
+ .. change::
+ :tags: orm
+ :tickets: 1622
+
+ relation primaryjoin and secondaryjoin now check that they
+ are column-expressions, not just clause elements. this prohibits
+ things like FROM expressions being placed there directly.
+
+ .. change::
+ :tags: orm
+ :tickets: 1415
+
+ `expression.null()` is fully understood the same way
+ None is when comparing an object/collection-referencing
+ attribute within query.filter(), filter_by(), etc.
+
+ .. change::
+ :tags: orm
+ :tickets: 1052
+
+ added "make_transient()" helper function which transforms a
+ persistent/ detached instance into a transient one (i.e.
+ deletes the instance_key and removes from any session.)
+
+ .. change::
+ :tags: orm
+ :tickets: 1339
+
+ the allow_null_pks flag on mapper() is deprecated, and
+ the feature is turned "on" by default. This means that
+ a row which has a non-null value for any of its primary key
+ columns will be considered an identity. The need for this
+ scenario typically only occurs when mapping to an outer join.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ the mechanics of "backref" have been fully merged into the
+ finer grained "back_populates" system, and take place entirely
+ within the _generate_backref() method of RelationProperty. This
+ makes the initialization procedure of RelationProperty
+ simpler and allows easier propagation of settings (such as from
+ subclasses of RelationProperty) into the reverse reference.
+ The internal BackRef() is gone and backref() returns a plain
+ tuple that is understood by RelationProperty.
+
+ .. change::
+ :tags: orm
+ :tickets: 1569
+
+ The version_id_col feature on mapper() will raise a warning when
+ used with dialects that don't support "rowcount" adequately.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ added "execution_options()" to Query, to so options can be
+ passed to the resulting statement. Currently only
+ Select-statements have these options, and the only option
+ used is "stream_results", and the only dialect which knows
+ "stream_results" is psycopg2.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Query.yield_per() will set the "stream_results" statement
+ option automatically.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Deprecated or removed:
+ * 'allow_null_pks' flag on mapper() is deprecated. It does
+ nothing now and the setting is "on" in all cases.
+ * 'transactional' flag on sessionmaker() and others is
+ removed. Use 'autocommit=True' to indicate 'transactional=False'.
+ * 'polymorphic_fetch' argument on mapper() is removed.
+ Loading can be controlled using the 'with_polymorphic'
+ option.
+ * 'select_table' argument on mapper() is removed. Use
+ 'with_polymorphic=("*", <some selectable>)' for this
+ functionality.
+ * 'proxy' argument on synonym() is removed. This flag
+ did nothing throughout 0.5, as the "proxy generation"
+ behavior is now automatic.
+ * Passing a single list of elements to eagerload(),
+ eagerload_all(), contains_eager(), lazyload(),
+ defer(), and undefer() instead of multiple positional
+ *args is deprecated.
+ * Passing a single list of elements to query.order_by(),
+ query.group_by(), query.join(), or query.outerjoin()
+ instead of multiple positional *args is deprecated.
+ * query.iterate_instances() is removed. Use query.instances().
+ * Query.query_from_parent() is removed. Use the
+ sqlalchemy.orm.with_parent() function to produce a
+ "parent" clause, or alternatively query.with_parent().
+ * query._from_self() is removed, use query.from_self()
+ instead.
+ * the "comparator" argument to composite() is removed.
+ Use "comparator_factory".
+ * RelationProperty._get_join() is removed.
+ * the 'echo_uow' flag on Session is removed. Use
+ logging on the "sqlalchemy.orm.unitofwork" name.
+ * session.clear() is removed. use session.expunge_all().
+ * session.save(), session.update(), session.save_or_update()
+ are removed. Use session.add() and session.add_all().
+ * the "objects" flag on session.flush() remains deprecated.
+ * the "dont_load=True" flag on session.merge() is deprecated
+ in favor of "load=False".
+ * ScopedSession.mapper remains deprecated. See the
+ usage recipe at
+ http://www.sqlalchemy.org/trac/wiki/UsageRecipes/SessionAwareMapper
+ * passing an InstanceState (internal SQLAlchemy state object) to
+ attributes.init_collection() or attributes.get_history() is
+ deprecated. These functions are public API and normally
+ expect a regular mapped object instance.
+ * the 'engine' parameter to declarative_base() is removed.
+ Use the 'bind' keyword argument.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ the "autocommit" flag on select() and text() as well
+ as select().autocommit() are deprecated - now call
+ .execution_options(autocommit=True) on either of those
+ constructs, also available directly on Connection and orm.Query.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ the autoincrement flag on column now indicates the column
+ which should be linked to cursor.lastrowid, if that method
+ is used. See the API docs for details.
+
+ .. change::
+ :tags: sql
+ :tickets: 1566
+
+ an executemany() now requires that all bound parameter
+ sets require that all keys are present which are
+ present in the first bound parameter set. The structure
+ and behavior of an insert/update statement is very much
+ determined by the first parameter set, including which
+ defaults are going to fire off, and a minimum of
+ guesswork is performed with all the rest so that performance
+ is not impacted. For this reason defaults would otherwise
+ silently "fail" for missing parameters, so this is now guarded
+ against.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ returning() support is native to insert(), update(),
+ delete(). Implementations of varying levels of
+ functionality exist for Postgresql, Firebird, MSSQL and
+ Oracle. returning() can be called explicitly with column
+ expressions which are then returned in the resultset,
+ usually via fetchone() or first().
+
+ insert() constructs will also use RETURNING implicitly to
+ get newly generated primary key values, if the database
+ version in use supports it (a version number check is
+ performed). This occurs if no end-user returning() was
+ specified.
+
+ .. change::
+ :tags: sql
+ :tickets: 1665
+
+ union(), intersect(), except() and other "compound" types
+ of statements have more consistent behavior w.r.t.
+ parenthesizing. Each compound element embedded within
+ another will now be grouped with parenthesis - previously,
+ the first compound element in the list would not be grouped,
+ as SQLite doesn't like a statement to start with
+ parenthesis. However, Postgresql in particular has
+ precedence rules regarding INTERSECT, and it is
+ more consistent for parenthesis to be applied equally
+ to all sub-elements. So now, the workaround for SQLite
+ is also what the workaround for PG was previously -
+ when nesting compound elements, the first one usually needs
+ ".alias().select()" called on it to wrap it inside
+ of a subquery.
+
+ .. change::
+ :tags: sql
+ :tickets: 1579
+
+ insert() and update() constructs can now embed bindparam()
+ objects using names that match the keys of columns. These
+ bind parameters will circumvent the usual route to those
+ keys showing up in the VALUES or SET clause of the generated
+ SQL.
+
+ .. change::
+ :tags: sql
+ :tickets: 1524
+
+ the Binary type now returns data as a Python string
+ (or a "bytes" type in Python 3), instead of the built-
+ in "buffer" type. This allows symmetric round trips
+ of binary data.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Added a tuple_() construct, allows sets of expressions
+ to be compared to another set, typically with IN against
+ composite primary keys or similar. Also accepts an
+ IN with multiple columns. The "scalar select can
+ have only one column" error message is removed - will
+ rely upon the database to report problems with
+ col mismatch.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ User-defined "default" and "onupdate" callables which
+ accept a context should now call upon
+ "context.current_parameters" to get at the dictionary
+ of bind parameters currently being processed. This
+ dict is available in the same way regardless of
+ single-execute or executemany-style statement execution.
+
+ .. change::
+ :tags: sql
+ :tickets: 1428
+
+ multi-part schema names, i.e. with dots such as
+ "dbo.master", are now rendered in select() labels
+ with underscores for dots, i.e. "dbo_master_table_column".
+ This is a "friendly" label that behaves better
+ in result sets.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ removed needless "counter" behavior with select()
+ labelnames that match a column name in the table,
+ i.e. generates "tablename_id" for "id", instead of
+ "tablename_id_1" in an attempt to avoid naming
+ conflicts, when the table has a column actually
+ named "tablename_id" - this is because
+ the labeling logic is always applied to all columns
+ so a naming conflict will never occur.
+
+ .. change::
+ :tags: sql
+ :tickets: 1628
+
+ calling expr.in_([]), i.e. with an empty list, emits a warning
+ before issuing the usual "expr != expr" clause. The
+ "expr != expr" can be very expensive, and it's preferred
+ that the user not issue in_() if the list is empty,
+ instead simply not querying, or modifying the criterion
+ as appropriate for more complex situations.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Added "execution_options()" to select()/text(), which set the
+ default options for the Connection. See the note in "engines".
+
+ .. change::
+ :tags: sql
+ :tickets: 1131
+
+ Deprecated or removed:
+ * "scalar" flag on select() is removed, use
+ select.as_scalar().
+ * "shortname" attribute on bindparam() is removed.
+ * postgres_returning, firebird_returning flags on
+ insert(), update(), delete() are deprecated, use
+ the new returning() method.
+ * fold_equivalents flag on join is deprecated (will remain
+ until is implemented)
+
+ .. change::
+ :tags: engines
+ :tickets: 443
+
+ transaction isolation level may be specified with
+ create_engine(... isolation_level="..."); available on
+ postgresql and sqlite.
+
+ .. change::
+ :tags: engines
+ :tickets:
+
+ Connection has execution_options(), generative method
+ which accepts keywords that affect how the statement
+ is executed w.r.t. the DBAPI. Currently supports
+ "stream_results", causes psycopg2 to use a server
+ side cursor for that statement, as well as
+ "autocommit", which is the new location for the "autocommit"
+ option from select() and text(). select() and
+ text() also have .execution_options() as well as
+ ORM Query().
+
+ .. change::
+ :tags: engines
+ :tickets: 1630
+
+ fixed the import for entrypoint-driven dialects to
+ not rely upon silly tb_info trick to determine import
+ error status.
+
+ .. change::
+ :tags: engines
+ :tickets:
+
+ added first() method to ResultProxy, returns first row and
+ closes result set immediately.
+
+ .. change::
+ :tags: engines
+ :tickets:
+
+ RowProxy objects are now pickleable, i.e. the object returned
+ by result.fetchone(), result.fetchall() etc.
+
+ .. change::
+ :tags: engines
+ :tickets:
+
+ RowProxy no longer has a close() method, as the row no longer
+ maintains a reference to the parent. Call close() on
+ the parent ResultProxy instead, or use autoclose.
+
+ .. change::
+ :tags: engines
+ :tickets: 1586
+
+ ResultProxy internals have been overhauled to greatly reduce
+ method call counts when fetching columns. Can provide a large
+ speed improvement (up to more than 100%) when fetching large
+ result sets. The improvement is larger when fetching columns
+ that have no type-level processing applied and when using
+ results as tuples (instead of as dictionaries). Many
+ thanks to Elixir's Gaëtan de Menten for this dramatic
+ improvement !
+
+ .. change::
+ :tags: engines
+ :tickets:
+
+ Databases which rely upon postfetch of "last inserted id"
+ to get at a generated sequence value (i.e. MySQL, MS-SQL)
+ now work correctly when there is a composite primary key
+ where the "autoincrement" column is not the first primary
+ key column in the table.
+
+ .. change::
+ :tags: engines
+ :tickets:
+
+ the last_inserted_ids() method has been renamed to the
+ descriptor "inserted_primary_key".
+
+ .. change::
+ :tags: engines
+ :tickets: 1554
+
+ setting echo=False on create_engine() now sets the loglevel
+ to WARN instead of NOTSET. This so that logging can be
+ disabled for a particular engine even if logging
+ for "sqlalchemy.engine" is enabled overall. Note that the
+ default setting of "echo" is `None`.
+
+ .. change::
+ :tags: engines
+ :tickets:
+
+ ConnectionProxy now has wrapper methods for all transaction
+ lifecycle events, including begin(), rollback(), commit()
+ begin_nested(), begin_prepared(), prepare(), release_savepoint(),
+ etc.
+
+ .. change::
+ :tags: engines
+ :tickets:
+
+ Connection pool logging now uses both INFO and DEBUG
+ log levels for logging. INFO is for major events such
+ as invalidated connections, DEBUG for all the acquire/return
+ logging. `echo_pool` can be False, None, True or "debug"
+ the same way as `echo` works.
+
+ .. change::
+ :tags: engines
+ :tickets: 1621
+
+ All pyodbc-dialects now support extra pyodbc-specific
+ kw arguments 'ansi', 'unicode_results', 'autocommit'.
+
+ .. change::
+ :tags: engines
+ :tickets:
+
+ the "threadlocal" engine has been rewritten and simplified
+ and now supports SAVEPOINT operations.
+
+ .. change::
+ :tags: engines
+ :tickets:
+
+ deprecated or removed
+ * result.last_inserted_ids() is deprecated. Use
+ result.inserted_primary_key
+ * dialect.get_default_schema_name(connection) is now
+ public via dialect.default_schema_name.
+ * the "connection" argument from engine.transaction() and
+ engine.run_callable() is removed - Connection itself
+ now has those methods. All four methods accept
+ *args and **kwargs which are passed to the given callable,
+ as well as the operating connection.
+
+ .. change::
+ :tags: schema
+ :tickets: 1541
+
+ the `__contains__()` method of `MetaData` now accepts
+ strings or `Table` objects as arguments. If given
+ a `Table`, the argument is converted to `table.key` first,
+ i.e. "[schemaname.]<tablename>"
+
+ .. change::
+ :tags: schema
+ :tickets:
+
+ deprecated MetaData.connect() and
+ ThreadLocalMetaData.connect() have been removed - send
+ the "bind" attribute to bind a metadata.
+
+ .. change::
+ :tags: schema
+ :tickets:
+
+ deprecated metadata.table_iterator() method removed (use
+ sorted_tables)
+
+ .. change::
+ :tags: schema
+ :tickets:
+
+ deprecated PassiveDefault - use DefaultClause.
+
+ .. change::
+ :tags: schema
+ :tickets:
+
+ the "metadata" argument is removed from DefaultGenerator
+ and subclasses, but remains locally present on Sequence,
+ which is a standalone construct in DDL.
+
+ .. change::
+ :tags: schema
+ :tickets:
+
+ Removed public mutability from Index and Constraint
+ objects:
+ - ForeignKeyConstraint.append_element()
+ - Index.append_column()
+ - UniqueConstraint.append_column()
+ - PrimaryKeyConstraint.add()
+ - PrimaryKeyConstraint.remove()
+ These should be constructed declaratively (i.e. in one
+ construction).
+
+ .. change::
+ :tags: schema
+ :tickets: 1545
+
+ The "start" and "increment" attributes on Sequence now
+ generate "START WITH" and "INCREMENT BY" by default,
+ on Oracle and Postgresql. Firebird doesn't support
+ these keywords right now.
+
+ .. change::
+ :tags: schema
+ :tickets:
+
+ UniqueConstraint, Index, PrimaryKeyConstraint all accept
+ lists of column names or column objects as arguments.
+
+ .. change::
+ :tags: schema
+ :tickets:
+
+ Other removed things:
+ - Table.key (no idea what this was for)
+ - Table.primary_key is not assignable - use
+ table.append_constraint(PrimaryKeyConstraint(...))
+ - Column.bind (get via column.table.bind)
+ - Column.metadata (get via column.table.metadata)
+ - Column.sequence (use column.default)
+ - ForeignKey(constraint=some_parent) (is now private _constraint)
+
+ .. change::
+ :tags: schema
+ :tickets:
+
+ The use_alter flag on ForeignKey is now a shortcut option
+ for operations that can be hand-constructed using the
+ DDL() event system. A side effect of this refactor is
+ that ForeignKeyConstraint objects with use_alter=True
+ will *not* be emitted on SQLite, which does not support
+ ALTER for foreign keys.
+
+ .. change::
+ :tags: schema
+ :tickets: 1605
+
+ ForeignKey and ForeignKeyConstraint objects now correctly
+ copy() all their public keyword arguments.
+
+ .. change::
+ :tags: Reflection/Inspection
+ :tickets:
+
+ Table reflection has been expanded and generalized into
+ a new API called "sqlalchemy.engine.reflection.Inspector".
+ The Inspector object provides fine-grained information about
+ a wide variety of schema information, with room for expansion,
+ including table names, column names, view definitions, sequences,
+ indexes, etc.
+
+ .. change::
+ :tags: Reflection/Inspection
+ :tickets:
+
+ Views are now reflectable as ordinary Table objects. The same
+ Table constructor is used, with the caveat that "effective"
+ primary and foreign key constraints aren't part of the reflection
+ results; these have to be specified explicitly if desired.
+
+ .. change::
+ :tags: Reflection/Inspection
+ :tickets:
+
+ The existing autoload=True system now uses Inspector underneath
+ so that each dialect need only return "raw" data about tables
+ and other objects - Inspector is the single place that information
+ is compiled into Table objects so that consistency is at a maximum.
+
+ .. change::
+ :tags: DDL
+ :tickets:
+
+ the DDL system has been greatly expanded. the DDL() class
+ now extends the more generic DDLElement(), which forms the basis
+ of many new constructs:
+
+ - CreateTable()
+ - DropTable()
+ - AddConstraint()
+ - DropConstraint()
+ - CreateIndex()
+ - DropIndex()
+ - CreateSequence()
+ - DropSequence()
+
+ These support "on" and "execute-at()" just like plain DDL()
+ does. User-defined DDLElement subclasses can be created and
+ linked to a compiler using the sqlalchemy.ext.compiler extension.
+
+ .. change::
+ :tags: DDL
+ :tickets:
+
+ The signature of the "on" callable passed to DDL() and
+ DDLElement() is revised as follows:
+
+ "ddl" - the DDLElement object itself.
+ "event" - the string event name.
+ "target" - previously "schema_item", the Table or
+ MetaData object triggering the event.
+ "connection" - the Connection object in use for the operation.
+ **kw - keyword arguments. In the case of MetaData before/after
+ create/drop, the list of Table objects for which
+ CREATE/DROP DDL is to be issued is passed as the kw
+ argument "tables". This is necessary for metadata-level
+ DDL that is dependent on the presence of specific tables.
+
+ - the "schema_item" attribute of DDL has been renamed to
+ "target".
+
+ .. change::
+ :tags: dialect, refactor
+ :tickets:
+
+ Dialect modules are now broken into database dialects
+ plus DBAPI implementations. Connect URLs are now
+ preferred to be specified using dialect+driver://...,
+ i.e. "mysql+mysqldb://scott:tiger@localhost/test". See
+ the 0.6 documentation for examples.
+
+ .. change::
+ :tags: dialect, refactor
+ :tickets:
+
+ the setuptools entrypoint for external dialects is now
+ called "sqlalchemy.dialects".
+
+ .. change::
+ :tags: dialect, refactor
+ :tickets:
+
+ the "owner" keyword argument is removed from Table. Use
+ "schema" to represent any namespaces to be prepended to
+ the table name.
+
+ .. change::
+ :tags: dialect, refactor
+ :tickets:
+
+ server_version_info becomes a static attribute.
+
+ .. change::
+ :tags: dialect, refactor
+ :tickets:
+
+ dialects receive an initialize() event on initial
+ connection to determine connection properties.
+
+ .. change::
+ :tags: dialect, refactor
+ :tickets:
+
+ dialects receive a visit_pool event have an opportunity
+ to establish pool listeners.
+
+ .. change::
+ :tags: dialect, refactor
+ :tickets:
+
+ cached TypeEngine classes are cached per-dialect class
+ instead of per-dialect.
+
+ .. change::
+ :tags: dialect, refactor
+ :tickets:
+
+ new UserDefinedType should be used as a base class for
+ new types, which preserves the 0.5 behavior of
+ get_col_spec().
+
+ .. change::
+ :tags: dialect, refactor
+ :tickets:
+
+ The result_processor() method of all type classes now
+ accepts a second argument "coltype", which is the DBAPI
+ type argument from cursor.description. This argument
+ can help some types decide on the most efficient processing
+ of result values.
+
+ .. change::
+ :tags: dialect, refactor
+ :tickets:
+
+ Deprecated Dialect.get_params() removed.
+
+ .. change::
+ :tags: dialect, refactor
+ :tickets:
+
+ Dialect.get_rowcount() has been renamed to a descriptor
+ "rowcount", and calls cursor.rowcount directly. Dialects
+ which need to hardwire a rowcount in for certain calls
+ should override the method to provide different behavior.
+
+ .. change::
+ :tags: dialect, refactor
+ :tickets: 1566
+
+ DefaultRunner and subclasses have been removed. The job
+ of this object has been simplified and moved into
+ ExecutionContext. Dialects which support sequences should
+ add a `fire_sequence()` method to their execution context
+ implementation.
+
+ .. change::
+ :tags: dialect, refactor
+ :tickets:
+
+ Functions and operators generated by the compiler now use
+ (almost) regular dispatch functions of the form
+ "visit_<opname>" and "visit_<funcname>_fn" to provide
+ customed processing. This replaces the need to copy the
+ "functions" and "operators" dictionaries in compiler
+ subclasses with straightforward visitor methods, and also
+ allows compiler subclasses complete control over
+ rendering, as the full _Function or _BinaryExpression
+ object is passed in.
+
+ .. change::
+ :tags: postgresql
+ :tickets:
+
+ New dialects: pg8000, zxjdbc, and pypostgresql
+ on py3k.
+
+ .. change::
+ :tags: postgresql
+ :tickets:
+
+ The "postgres" dialect is now named "postgresql" !
+ Connection strings look like:
+
+ postgresql://scott:tiger@localhost/test
+ postgresql+pg8000://scott:tiger@localhost/test
+
+ The "postgres" name remains for backwards compatiblity
+ in the following ways:
+
+ - There is a "postgres.py" dummy dialect which
+ allows old URLs to work, i.e.
+ postgres://scott:tiger@localhost/test
+
+ - The "postgres" name can be imported from the old
+ "databases" module, i.e. "from
+ sqlalchemy.databases import postgres" as well as
+ "dialects", "from sqlalchemy.dialects.postgres
+ import base as pg", will send a deprecation
+ warning.
+
+ - Special expression arguments are now named
+ "postgresql_returning" and "postgresql_where", but
+ the older "postgres_returning" and
+ "postgres_where" names still work with a
+ deprecation warning.
+
+ .. change::
+ :tags: postgresql
+ :tickets:
+
+ "postgresql_where" now accepts SQL expressions which
+ can also include literals, which will be quoted as needed.
+
+ .. change::
+ :tags: postgresql
+ :tickets:
+
+ The psycopg2 dialect now uses psycopg2's "unicode extension"
+ on all new connections, which allows all String/Text/etc.
+ types to skip the need to post-process bytestrings into
+ unicode (an expensive step due to its volume). Other
+ dialects which return unicode natively (pg8000, zxjdbc)
+ also skip unicode post-processing.
+
+ .. change::
+ :tags: postgresql
+ :tickets: 1511
+
+ Added new ENUM type, which exists as a schema-level
+ construct and extends the generic Enum type. Automatically
+ associates itself with tables and their parent metadata
+ to issue the appropriate CREATE TYPE/DROP TYPE
+ commands as needed, supports unicode labels, supports
+ reflection.
+
+ .. change::
+ :tags: postgresql
+ :tickets:
+
+ INTERVAL supports an optional "precision" argument
+ corresponding to the argument that PG accepts.
+
+ .. change::
+ :tags: postgresql
+ :tickets:
+
+ using new dialect.initialize() feature to set up
+ version-dependent behavior.
+
+ .. change::
+ :tags: postgresql
+ :tickets: 1279
+
+ somewhat better support for % signs in table/column names;
+ psycopg2 can't handle a bind parameter name of
+ %(foobar)s however and SQLA doesn't want to add overhead
+ just to treat that one non-existent use case.
+
+ .. change::
+ :tags: postgresql
+ :tickets: 1516
+
+ Inserting NULL into a primary key + foreign key column
+ will allow the "not null constraint" error to raise,
+ not an attempt to execute a nonexistent "col_id_seq"
+ sequence.
+
+ .. change::
+ :tags: postgresql
+ :tickets:
+
+ autoincrement SELECT statements, i.e. those which
+ select from a procedure that modifies rows, now work
+ with server-side cursor mode (the named cursor isn't
+ used for such statements.)
+
+ .. change::
+ :tags: postgresql
+ :tickets: 1636
+
+ postgresql dialect can properly detect pg "devel" version
+ strings, i.e. "8.5devel"
+
+ .. change::
+ :tags: postgresql
+ :tickets: 1619
+
+ The psycopg2 now respects the statement option
+ "stream_results". This option overrides the connection setting
+ "server_side_cursors". If true, server side cursors will be
+ used for the statement. If false, they will not be used, even
+ if "server_side_cursors" is true on the
+ connection.
+
+ .. change::
+ :tags: mysql
+ :tickets:
+
+ New dialects: oursql, a new native dialect,
+ MySQL Connector/Python, a native Python port of MySQLdb,
+ and of course zxjdbc on Jython.
+
+ .. change::
+ :tags: mysql
+ :tickets:
+
+ VARCHAR/NVARCHAR will not render without a length, raises
+ an error before passing to MySQL. Doesn't impact
+ CAST since VARCHAR is not allowed in MySQL CAST anyway,
+ the dialect renders CHAR/NCHAR in those cases.
+
+ .. change::
+ :tags: mysql
+ :tickets:
+
+ all the _detect_XXX() functions now run once underneath
+ dialect.initialize()
+
+ .. change::
+ :tags: mysql
+ :tickets: 1279
+
+ somewhat better support for % signs in table/column names;
+ MySQLdb can't handle % signs in SQL when executemany() is used,
+ and SQLA doesn't want to add overhead just to treat that one
+ non-existent use case.
+
+ .. change::
+ :tags: mysql
+ :tickets:
+
+ the BINARY and MSBinary types now generate "BINARY" in all
+ cases. Omitting the "length" parameter will generate
+ "BINARY" with no length. Use BLOB to generate an unlengthed
+ binary column.
+
+ .. change::
+ :tags: mysql
+ :tickets:
+
+ the "quoting='quoted'" argument to MSEnum/ENUM is deprecated.
+ It's best to rely upon the automatic quoting.
+
+ .. change::
+ :tags: mysql
+ :tickets:
+
+ ENUM now subclasses the new generic Enum type, and also handles
+ unicode values implicitly, if the given labelnames are unicode
+ objects.
+
+ .. change::
+ :tags: mysql
+ :tickets: 1539
+
+ a column of type TIMESTAMP now defaults to NULL if
+ "nullable=False" is not passed to Column(), and no default
+ is present. This is now consistent with all other types,
+ and in the case of TIMESTAMP explictly renders "NULL"
+ due to MySQL's "switching" of default nullability
+ for TIMESTAMP columns.
+
+ .. change::
+ :tags: oracle
+ :tickets:
+
+ unit tests pass 100% with cx_oracle !
+
+ .. change::
+ :tags: oracle
+ :tickets:
+
+ support for cx_Oracle's "native unicode" mode which does
+ not require NLS_LANG to be set. Use the latest 5.0.2 or
+ later of cx_oracle.
+
+ .. change::
+ :tags: oracle
+ :tickets:
+
+ an NCLOB type is added to the base types.
+
+ .. change::
+ :tags: oracle
+ :tickets:
+
+ use_ansi=False won't leak into the FROM/WHERE clause of
+ a statement that's selecting from a subquery that also
+ uses JOIN/OUTERJOIN.
+
+ .. change::
+ :tags: oracle
+ :tickets: 1467
+
+ added native INTERVAL type to the dialect. This supports
+ only the DAY TO SECOND interval type so far due to lack
+ of support in cx_oracle for YEAR TO MONTH.
+
+ .. change::
+ :tags: oracle
+ :tickets:
+
+ usage of the CHAR type results in cx_oracle's
+ FIXED_CHAR dbapi type being bound to statements.
+
+ .. change::
+ :tags: oracle
+ :tickets: 885
+
+ the Oracle dialect now features NUMBER which intends
+ to act justlike Oracle's NUMBER type. It is the primary
+ numeric type returned by table reflection and attempts
+ to return Decimal()/float/int based on the precision/scale
+ parameters.
+
+ .. change::
+ :tags: oracle
+ :tickets:
+
+ func.char_length is a generic function for LENGTH
+
+ .. change::
+ :tags: oracle
+ :tickets:
+
+ ForeignKey() which includes onupdate=<value> will emit a
+ warning, not emit ON UPDATE CASCADE which is unsupported
+ by oracle
+
+ .. change::
+ :tags: oracle
+ :tickets:
+
+ the keys() method of RowProxy() now returns the result
+ column names *normalized* to be SQLAlchemy case
+ insensitive names. This means they will be lower case for
+ case insensitive names, whereas the DBAPI would normally
+ return them as UPPERCASE names. This allows row keys() to
+ be compatible with further SQLAlchemy operations.
+
+ .. change::
+ :tags: oracle
+ :tickets:
+
+ using new dialect.initialize() feature to set up
+ version-dependent behavior.
+
+ .. change::
+ :tags: oracle
+ :tickets: 1125
+
+ using types.BigInteger with Oracle will generate
+ NUMBER(19)
+
+ .. change::
+ :tags: oracle
+ :tickets:
+
+ "case sensitivity" feature will detect an all-lowercase
+ case-sensitive column name during reflect and add
+ "quote=True" to the generated Column, so that proper
+ quoting is maintained.
+
+ .. change::
+ :tags: firebird
+ :tickets:
+
+ the keys() method of RowProxy() now returns the result
+ column names *normalized* to be SQLAlchemy case
+ insensitive names. This means they will be lower case for
+ case insensitive names, whereas the DBAPI would normally
+ return them as UPPERCASE names. This allows row keys() to
+ be compatible with further SQLAlchemy operations.
+
+ .. change::
+ :tags: firebird
+ :tickets:
+
+ using new dialect.initialize() feature to set up
+ version-dependent behavior.
+
+ .. change::
+ :tags: firebird
+ :tickets:
+
+ "case sensitivity" feature will detect an all-lowercase
+ case-sensitive column name during reflect and add
+ "quote=True" to the generated Column, so that proper
+ quoting is maintained.
+
+ .. change::
+ :tags: mssql
+ :tickets:
+
+ MSSQL + Pyodbc + FreeTDS now works for the most part,
+ with possible exceptions regarding binary data as well as
+ unicode schema identifiers.
+
+ .. change::
+ :tags: mssql
+ :tickets:
+
+ the "has_window_funcs" flag is removed. LIMIT/OFFSET
+ usage will use ROW NUMBER as always, and if on an older
+ version of SQL Server, the operation fails. The behavior
+ is exactly the same except the error is raised by SQL
+ server instead of the dialect, and no flag setting is
+ required to enable it.
+
+ .. change::
+ :tags: mssql
+ :tickets:
+
+ the "auto_identity_insert" flag is removed. This feature
+ always takes effect when an INSERT statement overrides a
+ column that is known to have a sequence on it. As with
+ "has_window_funcs", if the underlying driver doesn't
+ support this, then you can't do this operation in any
+ case, so there's no point in having a flag.
+
+ .. change::
+ :tags: mssql
+ :tickets:
+
+ using new dialect.initialize() feature to set up
+ version-dependent behavior.
+
+ .. change::
+ :tags: mssql
+ :tickets:
+
+ removed references to sequence which is no longer used.
+ implicit identities in mssql work the same as implicit
+ sequences on any other dialects. Explicit sequences are
+ enabled through the use of "default=Sequence()". See
+ the MSSQL dialect documentation for more information.
+
+ .. change::
+ :tags: sqlite
+ :tickets:
+
+ DATE, TIME and DATETIME types can now take optional storage_format
+ and regexp argument. storage_format can be used to store those types
+ using a custom string format. regexp allows to use a custom regular
+ expression to match string values from the database.
+
+ .. change::
+ :tags: sqlite
+ :tickets:
+
+ Time and DateTime types now use by a default a stricter regular
+ expression to match strings from the database. Use the regexp
+ argument if you are using data stored in a legacy format.
+
+ .. change::
+ :tags: sqlite
+ :tickets:
+
+ __legacy_microseconds__ on SQLite Time and DateTime types is not
+ supported anymore. You should use the storage_format argument
+ instead.
+
+ .. change::
+ :tags: sqlite
+ :tickets:
+
+ Date, Time and DateTime types are now stricter in what they accept as
+ bind parameters: Date type only accepts date objects (and datetime
+ ones, because they inherit from date), Time only accepts time
+ objects, and DateTime only accepts date and datetime objects.
+
+ .. change::
+ :tags: sqlite
+ :tickets: 1016
+
+ Table() supports a keyword argument "sqlite_autoincrement", which
+ applies the SQLite keyword "AUTOINCREMENT" to the single integer
+ primary key column when generating DDL. Will prevent generation of
+ a separate PRIMARY KEY constraint.
+
+ .. change::
+ :tags: types
+ :tickets:
+
+ The construction of types within dialects has been totally
+ overhauled. Dialects now define publically available types
+ as UPPERCASE names exclusively, and internal implementation
+ types using underscore identifiers (i.e. are private).
+ The system by which types are expressed in SQL and DDL
+ has been moved to the compiler system. This has the
+ effect that there are much fewer type objects within
+ most dialects. A detailed document on this architecture
+ for dialect authors is in
+ lib/sqlalchemy/dialects/type_migration_guidelines.txt .
+
+ .. change::
+ :tags: types
+ :tickets:
+
+ Types no longer make any guesses as to default
+ parameters. In particular, Numeric, Float, NUMERIC,
+ FLOAT, DECIMAL don't generate any length or scale unless
+ specified.
+
+ .. change::
+ :tags: types
+ :tickets: 1664
+
+ types.Binary is renamed to types.LargeBinary, it only
+ produces BLOB, BYTEA, or a similar "long binary" type.
+ New base BINARY and VARBINARY
+ types have been added to access these MySQL/MS-SQL specific
+ types in an agnostic way.
+
+ .. change::
+ :tags: types
+ :tickets:
+
+ String/Text/Unicode types now skip the unicode() check
+ on each result column value if the dialect has
+ detected the DBAPI as returning Python unicode objects
+ natively. This check is issued on first connect
+ using "SELECT CAST 'some text' AS VARCHAR(10)" or
+ equivalent, then checking if the returned object
+ is a Python unicode. This allows vast performance
+ increases for native-unicode DBAPIs, including
+ pysqlite/sqlite3, psycopg2, and pg8000.
+
+ .. change::
+ :tags: types
+ :tickets:
+
+ Most types result processors have been checked for possible speed
+ improvements. Specifically, the following generic types have been
+ optimized, resulting in varying speed improvements:
+ Unicode, PickleType, Interval, TypeDecorator, Binary.
+ Also the following dbapi-specific implementations have been improved:
+ Time, Date and DateTime on Sqlite, ARRAY on Postgresql,
+ Time on MySQL, Numeric(as_decimal=False) on MySQL, oursql and
+ pypostgresql, DateTime on cx_oracle and LOB-based types on cx_oracle.
+
+ .. change::
+ :tags: types
+ :tickets:
+
+ Reflection of types now returns the exact UPPERCASE
+ type within types.py, or the UPPERCASE type within
+ the dialect itself if the type is not a standard SQL
+ type. This means reflection now returns more accurate
+ information about reflected types.
+
+ .. change::
+ :tags: types
+ :tickets: 1511, 1109
+
+ Added a new Enum generic type. Enum is a schema-aware object
+ to support databases which require specific DDL in order to
+ use enum or equivalent; in the case of PG it handles the
+ details of `CREATE TYPE`, and on other databases without
+ native enum support will by generate VARCHAR + an inline CHECK
+ constraint to enforce the enum.
+
+ .. change::
+ :tags: types
+ :tickets: 1467
+
+ The Interval type includes a "native" flag which controls
+ if native INTERVAL types (postgresql + oracle) are selected
+ if available, or not. "day_precision" and "second_precision"
+ arguments are also added which propagate as appropriately
+ to these native types. Related to.
+
+ .. change::
+ :tags: types
+ :tickets: 1589
+
+ The Boolean type, when used on a backend that doesn't
+ have native boolean support, will generate a CHECK
+ constraint "col IN (0, 1)" along with the int/smallint-
+ based column type. This can be switched off if
+ desired with create_constraint=False.
+ Note that MySQL has no native boolean *or* CHECK constraint
+ support so this feature isn't available on that platform.
+
+ .. change::
+ :tags: types
+ :tickets:
+
+ PickleType now uses == for comparison of values when
+ mutable=True, unless the "comparator" argument with a
+ comparsion function is specified to the type. Objects
+ being pickled will be compared based on identity (which
+ defeats the purpose of mutable=True) if __eq__() is not
+ overridden or a comparison function is not provided.
+
+ .. change::
+ :tags: types
+ :tickets:
+
+ The default "precision" and "scale" arguments of Numeric
+ and Float have been removed and now default to None.
+ NUMERIC and FLOAT will be rendered with no numeric
+ arguments by default unless these values are provided.
+
+ .. change::
+ :tags: types
+ :tickets:
+
+ AbstractType.get_search_list() is removed - the games
+ that was used for are no longer necessary.
+
+ .. change::
+ :tags: types
+ :tickets: 1125
+
+ Added a generic BigInteger type, compiles to
+ BIGINT or NUMBER(19).
+
+ .. change::
+ :tags: types
+ :tickets:
+
+ sqlsoup has been overhauled to explicitly support an 0.5 style
+ session, using autocommit=False, autoflush=True. Default
+ behavior of SQLSoup now requires the usual usage of commit()
+ and rollback(), which have been added to its interface. An
+ explcit Session or scoped_session can be passed to the
+ constructor, allowing these arguments to be overridden.
+
+ .. change::
+ :tags: types
+ :tickets:
+
+ sqlsoup db.<sometable>.update() and delete() now call
+ query(cls).update() and delete(), respectively.
+
+ .. change::
+ :tags: types
+ :tickets:
+
+ sqlsoup now has execute() and connection(), which call upon
+ the Session methods of those names, ensuring that the bind is
+ in terms of the SqlSoup object's bind.
+
+ .. change::
+ :tags: types
+ :tickets:
+
+ sqlsoup objects no longer have the 'query' attribute - it's
+ not needed for sqlsoup's usage paradigm and it gets in the
+ way of a column that is actually named 'query'.
+
+ .. change::
+ :tags: types
+ :tickets: 1259
+
+ The signature of the proxy_factory callable passed to
+ association_proxy is now (lazy_collection, creator,
+ value_attr, association_proxy), adding a fourth argument
+ that is the parent AssociationProxy argument. Allows
+ serializability and subclassing of the built in collections.
+
+ .. change::
+ :tags: types
+ :tickets: 1372
+
+ association_proxy now has basic comparator methods .any(),
+ .has(), .contains(), ==, !=, thanks to Scott Torborg.
+
+ .. change::
+ :tags: examples
+ :tickets:
+
+ The "query_cache" examples have been removed, and are replaced
+ with a fully comprehensive approach that combines the usage of
+ Beaker with SQLAlchemy. New query options are used to indicate
+ the caching characteristics of a particular Query, which
+ can also be invoked deep within an object graph when lazily
+ loading related objects. See /examples/beaker_caching/README.
--- /dev/null
+
+==============
+0.7 Changelog
+==============
+
+
+.. changelog::
+ :version: 0.7.10
+ :released:
+
+ .. change::
+ :tags: orm, bug
+ :tickets: 2583
+
+ 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.
+
+ .. change::
+ :tags: oracle, bug
+ :tickets: 2561
+
+ 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.
+
+ .. change::
+ :tags: feature, mysql
+ :tickets: 2523
+
+ Added "raise_on_warnings" flag to OurSQL
+ dialect.
+
+ .. change::
+ :tags: feature, mysql
+ :tickets: 2554
+
+ Added "read_timeout" flag to MySQLdb
+ dialect.
+
+.. changelog::
+ :version: 0.7.9
+ :released: Mon Oct 01 2012
+
+ .. change::
+ :tags: orm, bug
+ :tickets:
+
+ 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
+ explicitly.
+
+ .. change::
+ :tags: orm, bug
+ :tickets:
+
+ A warning is emitted when lazy='dynamic'
+ is combined with uselist=False. This is an
+ exception raise in 0.8.
+
+ .. change::
+ :tags: orm, bug
+ :tickets:
+
+ 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
+ error is raised now.
+
+ .. change::
+ :tags: orm, bug
+ :tickets: 2539
+
+ 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.
+
+ .. change::
+ :tags: orm, bug
+ :tickets: 2566
+
+ 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.
+
+ .. change::
+ :tags: bug, sql
+ :tickets: 2571
+
+ Fixed the DropIndex construct to support
+ an Index associated with a Table in a remote
+ schema.
+
+ .. change::
+ :tags: bug, sql
+ :tickets: 2574
+
+ Fixed bug in over() construct whereby
+ passing an empty list for either partition_by
+ or order_by, as opposed to None, would fail
+ to generate correctly.
+ Courtesy Gunnlaugur Þór Briem.
+
+ .. change::
+ :tags: bug, sql
+ :tickets: 2521
+
+ 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.
+
+ .. change::
+ :tags: bug, sql
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: bug, sql
+ :tickets: 2512
+
+ 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.
+
+ .. change::
+ :tags: bug, sql
+ :tickets: 2518
+
+ Fixed regression introduced in 0.7.6
+ whereby the FROM list of a SELECT statement
+ could be incorrect in certain "clone+replace"
+ scenarios.
+
+ .. change::
+ :tags: bug, sql
+ :tickets: 2552
+
+ 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
+ UNION.
+
+ .. change::
+ :tags: bug, sql
+ :tickets: 2558
+
+ 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
+ mechanism by which
+ query(MyClass).from_statement(some_statement)
+ 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.
+
+ .. change::
+ :tags: bug, sql
+ :tickets: 2544
+
+ Added missing operators is_(), isnot()
+ to the ColumnOperators base, so that these long-available
+ operators are present as methods like all
+ the other operators.
+
+ .. change::
+ :tags: bug, sql
+ :tickets: 2525
+
+ 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.
+
+ .. change::
+ :tags: engine, bug
+ :tickets: 2522
+
+ 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.
+
+ .. change::
+ :tags: engine, feature
+ :tickets: 2516
+
+ 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.
+
+ .. change::
+ :tags: engine, bug
+ :tickets: 2529
+
+ Added gaerdbms import to mysql/__init__.py,
+ the absense of which was preventing the new
+ GAE dialect from being loaded.
+
+ .. change::
+ :tags: engine, bug
+ :tickets: 2553
+
+ 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.
+
+ .. change::
+ :tags: engine, bug
+ :tickets:
+
+ Fixed the repr() of Enum to include
+ the "name" and "native_enum" flags. Helps
+ Alembic autogenerate.
+
+ .. change::
+ :tags: sqlite, bug
+ :tickets: 2568
+
+ 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""").
+
+ .. change::
+ :tags: sqlite, bug
+ :tickets: 2265
+
+ 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.
+
+ .. change::
+ :tags: sqlite, feature
+ :tickets:
+
+ Added support for the localtimestamp()
+ SQL function implemented in SQLite, courtesy
+ Richard Mitchell.
+
+ .. change::
+ :tags: postgresql, bug
+ :tickets: 2531
+
+ 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..
+
+ .. change::
+ :tags: postgresql, bug
+ :tickets: 2570
+
+ 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.
+
+ .. change::
+ :tags: bug, mysql
+ :tickets:
+
+ Updated mysqlconnector interface to use
+ updated "client flag" and "charset" APIs,
+ courtesy David McNelis.
+
+ .. change::
+ :tags: mssql, bug
+ :tickets: 2538
+
+ 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
+ sayap
+
+ .. change::
+ :tags: mssql, bug
+ :tickets: 2545
+
+ 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.
+
+ .. change::
+ :tags: mssql, bug
+ :tickets:
+
+ Fixed bug where reflection of primary key constraint
+ would double up columns if the same constraint/table
+ existed in multiple schemas.
+
+.. changelog::
+ :version: 0.7.8
+ :released: Sat Jun 16 2012
+
+ .. change::
+ :tags: orm, bug
+ :tickets: 2480
+
+ 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
+ result.
+
+ .. change::
+ :tags: orm, bug
+ :tickets: 2491, 1892
+
+ 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 as this was supposed
+ to be part of that, this is.
+
+ .. change::
+ :tags: orm, feature
+ :tickets:
+
+ The 'objects' argument to
+ flush() is no longer deprecated, as some
+ valid use cases have been identified.
+
+ .. change::
+ :tags: orm, bug
+ :tickets: 2508
+
+ Fixed identity_key() function which
+ was not accepting a scalar argument
+ for the identity. .
+
+ .. change::
+ :tags: orm, bug
+ :tickets: 2497
+
+ Fixed bug whereby populate_existing
+ option would not propagate to subquery
+ eager loaders. .
+
+ .. change::
+ :tags: bug, sql
+ :tickets: 2499
+
+ added BIGINT to types.__all__,
+ BIGINT, BINARY, VARBINARY to sqlalchemy
+ module namespace, plus test to ensure
+ this breakage doesn't occur again.
+
+ .. change::
+ :tags: bug, sql
+ :tickets: 2490
+
+ Repaired common table expression
+ rendering to function correctly when the
+ SELECT statement contains UNION or other
+ compound expressions, courtesy btbuilder.
+
+ .. change::
+ :tags: bug, sql
+ :tickets: 2482
+
+ Fixed bug whereby append_column()
+ wouldn't function correctly on a cloned
+ select() construct, courtesy
+ Gunnlaugur Þór Briem.
+
+ .. change::
+ :tags: engine, bug
+ :tickets: 2489
+
+ 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.
+
+ .. change::
+ :tags: engine, bug
+ :tickets: 2503
+
+ 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..
+
+ .. change::
+ :tags: postgresql, bug
+ :tickets: 2510
+
+ removed unnecessary table clause when
+ reflecting enums,. Courtesy
+ Gunnlaugur Þór Briem.
+
+ .. change::
+ :tags: oracle, bug
+ :tickets: 2483
+
+ Added ROWID to oracle.*.
+
+ .. change::
+ :tags: feature, mysql
+ :tickets: 2484
+
+ Added a new dialect for Google App
+ Engine. Courtesy Richie Foreman.
+
+.. changelog::
+ :version: 0.7.7
+ :released: Sat May 05 2012
+
+ .. change::
+ :tags: orm, bug
+ :tickets: 2477
+
+ 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..
+
+ .. change::
+ :tags: orm, feature
+ :tickets: 2443
+
+ Added prefix_with() method
+ to Query, calls upon select().prefix_with()
+ to allow placement of MySQL SELECT
+ directives in statements. Courtesy
+ Diana Clarke
+
+ .. change::
+ :tags: orm, bug
+ :tickets: 2409
+
+ Fixed bug in 0.7.6 introduced by whereby column_mapped_collection
+ used against columns that were mapped as
+ joins or other indirect selectables
+ would fail to function.
+
+ .. change::
+ :tags: orm, feature
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm, bug
+ :tickets: 2449
+
+ 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.
+
+ .. change::
+ :tags: orm, bug
+ :tickets: 2453
+
+ Fixed bug in expression annotation
+ mechanics which could lead to incorrect
+ rendering of SELECT statements with aliases
+ and joins, particularly when using
+ column_property().
+
+ .. change::
+ :tags: orm, bug
+ :tickets: 2454
+
+ Fixed bug which would prevent
+ OrderingList from being pickleable. Courtesy Jeff Dairiki
+
+ .. change::
+ :tags: orm, bug
+ :tickets:
+
+ Fixed bug in relationship comparisons
+ whereby calling unimplemented methods like
+ SomeClass.somerelationship.like() would
+ produce a recursion overflow, instead
+ of NotImplementedError.
+
+ .. change::
+ :tags: bug, sql
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: feature, sql
+ :tickets:
+
+ Added new connection event
+ dbapi_error(). Is called for all DBAPI-level
+ errors passing the original DBAPI exception
+ before SQLAlchemy modifies the state
+ of the cursor.
+
+ .. change::
+ :tags: bug, sql
+ :tickets:
+
+ If conn.begin() fails when calling
+ "with engine.begin()", the newly acquired
+ Connection is closed explicitly before
+ propagating the exception onward normally.
+
+ .. change::
+ :tags: bug, sql
+ :tickets: 2474
+
+ Add BINARY, VARBINARY to types.__all__.
+
+ .. change::
+ :tags: mssql, feature
+ :tickets:
+
+ Added interim create_engine flag
+ supports_unicode_binds to PyODBC dialect,
+ to force whether or not the dialect
+ passes Python unicode literals to PyODBC
+ or not.
+
+ .. change::
+ :tags: mssql, bug
+ :tickets:
+
+ 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"
+ set to False.
+
+ .. change::
+ :tags: mssql, bug
+ :tickets: 2468
+
+ 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.
+
+ .. change::
+ :tags: postgresql, feature
+ :tickets: 2445
+
+ Added new for_update/with_lockmode()
+ options for Postgresql: for_update="read"/
+ with_lockmode("read"),
+ for_update="read_nowait"/
+ with_lockmode("read_nowait").
+ These emit "FOR SHARE" and "FOR SHARE NOWAIT",
+ respectively. Courtesy Diana Clarke
+
+ .. change::
+ :tags: postgresql, bug
+ :tickets: 2473
+
+ removed unnecessary table clause
+ when reflecting domains.
+
+ .. change::
+ :tags: bug, mysql
+ :tickets: 2460
+
+ 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
+ Dairiki.
+
+ .. change::
+ :tags: bug, mysql
+ :tickets:
+
+ Fixed bug whereby get_view_names() for
+ "information_schema" schema would fail
+ to retrieve views marked as "SYSTEM VIEW".
+ courtesy Matthew Turland.
+
+ .. change::
+ :tags: bug, mysql
+ :tickets: 2467
+
+ 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.
+
+ .. change::
+ :tags: sqlite, feature
+ :tickets: 2475
+
+ Added SQLite execution option
+ "sqlite_raw_colnames=True", will bypass
+ attempts to remove "." from column names
+ returned by SQLite cursor.description.
+
+.. changelog::
+ :version: 0.7.6
+ :released: Wed Mar 14 2012
+
+ .. change::
+ :tags: orm, bug
+ :tickets: 2424
+
+ 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.
+
+ .. change::
+ :tags: orm, bug
+ :tickets: 2425
+
+ 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.
+
+ .. change::
+ :tags: orm, feature
+ :tickets:
+
+ Added "no_autoflush" context
+ manager to Session, used with with:
+ will temporarily disable autoflush.
+
+ .. change::
+ :tags: orm, feature
+ :tickets: 1859
+
+ Added cte() method to Query,
+ invokes common table expression support
+ from the Core (see below).
+
+ .. change::
+ :tags: orm, bug
+ :tickets: 2403
+
+ 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.
+
+ .. change::
+ :tags: orm, bug
+ :tickets: 2409
+
+ Fixed bug whereby objects using
+ attribute_mapped_collection or
+ column_mapped_collection could not be
+ pickled.
+
+ .. change::
+ :tags: orm, bug
+ :tickets: 2406
+
+ Fixed bug whereby MappedCollection
+ would not get the appropriate collection
+ instrumentation if it were only used
+ in a custom subclass that used
+ @collection.internally_instrumented.
+
+ .. change::
+ :tags: orm, bug
+ :tickets: 2419
+
+ 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.
+
+ .. change::
+ :tags: orm, bug
+ :tickets: 2417
+
+ Fixed the repr() for CascadeOptions to
+ include refresh-expire. Also reworked
+ CascadeOptions to be a <frozenset>.
+
+ .. change::
+ :tags: orm, feature
+ :tickets: 2400
+
+ Added the ability to query for
+ Table-bound column names when using
+ query(sometable).filter_by(colname=value).
+
+ .. change::
+ :tags: orm, bug
+ :tickets:
+
+ 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
+ as reflected.
+
+ .. change::
+ :tags: orm, bug
+ :tickets: 2390
+
+ 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.
+
+ .. change::
+ :tags: orm, bug
+ :tickets: 2352
+
+ 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.
+
+ .. change::
+ :tags: bug, sql
+ :tickets: 2427
+
+ 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.
+
+ .. change::
+ :tags: bug, sql
+ :tickets: 2398
+
+ 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.
+
+ .. change::
+ :tags: feature, sql
+ :tickets: 1859
+
+ 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.
+
+ .. change::
+ :tags: bug, sql
+ :tickets: 2392
+
+ 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.
+
+ .. change::
+ :tags: bug, sql
+ :tickets: 2413
+
+ 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.
+
+ .. change::
+ :tags: bug, sql
+ :tickets: 2396
+
+ 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.
+
+ .. change::
+ :tags: bug, sql
+ :tickets: 2402
+
+ Fixed bug in new "autoload_replace" flag
+ which would fail to preserve the primary
+ key constraint of the reflected table.
+
+ .. change::
+ :tags: bug, sql
+ :tickets: 2380
+
+ Index will raise when arguments passed
+ cannot be interpreted as columns or expressions.
+ Will warn when Index is created
+ with no columns at all.
+
+ .. change::
+ :tags: engine, feature
+ :tickets: 2407
+
+ 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).
+
+ .. change::
+ :tags: engine, bug
+ :tickets:
+
+ Added execution_options() call to
+ MockConnection (i.e., that used with
+ strategy="mock") which acts as a pass through
+ for arguments.
+
+ .. change::
+ :tags: engine, feature
+ :tickets: 2378
+
+ 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.
+
+ .. change::
+ :tags: engine, feature
+ :tickets:
+
+ Added some decent context managers
+ to Engine, Connection:
+
+ with engine.begin() as conn:
+ <work with conn in a transaction>
+
+ and:
+
+ with engine.connect() as conn:
+ <work with conn>
+
+ Both close out the connection when done,
+ commit or rollback transaction with errors
+ on engine.begin().
+
+ .. change::
+ :tags: sqlite, bug
+ :tickets: 2432
+
+ 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.
+
+ .. change::
+ :tags: mssql, feature
+ :tickets: 2430
+
+ Added support for MSSQL INSERT,
+ UPDATE, and DELETE table hints, using
+ new with_hint() method on UpdateBase.
+
+ .. change::
+ :tags: feature, mysql
+ :tickets: 2386
+
+ 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.
+
+ .. change::
+ :tags: feature, mysql
+ :tickets: 2394
+
+ Added support for the "isolation_level"
+ parameter to all MySQL dialects. Thanks
+ to mu_mind for the patch here.
+
+ .. change::
+ :tags: oracle, feature
+ :tickets: 2399
+
+ 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
+ Decimal.
+
+ .. change::
+ :tags: oracle, bug
+ :tickets: 2401
+
+ Added missing compilation support for
+ LONG
+
+ .. change::
+ :tags: oracle, bug
+ :tickets: 2435
+
+ Added 'LEVEL' to the list of reserved
+ words for Oracle.
+
+ .. change::
+ :tags: examples, bug
+ :tickets:
+
+ 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
+ columns clause, etc.
+
+ .. change::
+ :tags: orm, bug
+ :tickets: 2389
+
+ 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.
+
+ .. change::
+ :tags: orm, bug
+ :tickets: 2345
+
+ Fixed regression from 0.7.4 whereby
+ using an already instrumented column from a
+ superclass as "polymorphic_on" failed to resolve
+ the underlying Column.
+
+ .. change::
+ :tags: orm, bug
+ :tickets: 2370
+
+ Raise an exception if xyzload_all() is
+ used inappropriately with two non-connected
+ relationships.
+
+ .. change::
+ :tags: orm, feature
+ :tickets:
+
+ Added "class_registry" argument to
+ declarative_base(). Allows two or more declarative
+ bases to share the same registry of class names.
+
+ .. change::
+ :tags: orm, feature
+ :tickets:
+
+ query.filter() accepts multiple
+ criteria which will join via AND, i.e.
+ query.filter(x==y, z>q, ...)
+
+ .. change::
+ :tags: orm, feature
+ :tickets: 2351
+
+ 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 !
+
+ .. change::
+ :tags: orm, bug
+ :tickets: 2367
+
+ 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 ??)
+
+ .. change::
+ :tags: orm, bug
+ :tickets:
+
+ Fixed bug whereby hybrid_property didn't
+ work as a kw arg in any(), has().
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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
+ to load.
+
+ .. change::
+ :tags: orm, bug
+ :tickets: 2371
+
+ ensure pickleability of all ORM exceptions
+ for multiprocessing compatibility.
+
+ .. change::
+ :tags: orm, bug
+ :tickets: 2353
+
+ 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.
+
+ .. change::
+ :tags: orm, bug
+ :tickets: 2362
+
+ 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.
+
+ .. change::
+ :tags: orm, bug
+ :tickets: 2374
+
+ 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.
+
+ .. change::
+ :tags: orm, feature
+ :tickets: 2356
+
+ New declarative reflection example
+ added, illustrates how best to mix table reflection
+ with declarative as well as uses some new features
+ from.
+
+ .. change::
+ :tags: feature, sql
+ :tickets: 2356
+
+ 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.
+
+ .. change::
+ :tags: bug, sql
+ :tickets: 2356
+
+ 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.
+
+ .. change::
+ :tags: feature, sql
+ :tickets:
+
+ Added "false()" and "true()" expression
+ constructs to sqlalchemy.sql namespace, though
+ not part of __all__ as of yet.
+
+ .. change::
+ :tags: feature, sql
+ :tickets: 2361
+
+ 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.
+
+ .. change::
+ :tags: bug, sql
+ :tickets: 2381
+
+ Fixed issue where the "required" exception
+ would not be raised for bindparam() with required=True,
+ if the statement were given no parameters at all.
+
+ .. change::
+ :tags: engine, bug
+ :tickets: 2371
+
+ Added __reduce__ to StatementError,
+ DBAPIError, column errors so that exceptions
+ are pickleable, as when using multiprocessing.
+ However, not
+ all DBAPIs support this yet, such as
+ psycopg2.
+
+ .. change::
+ :tags: engine, bug
+ :tickets: 2382
+
+ 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.
+
+ .. change::
+ :tags: engine, bug
+ :tickets: 2377
+
+ 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
+ set row.
+
+ .. change::
+ :tags: engine, bug
+ :tickets: 2384
+
+ Fixed bug in "mock" strategy whereby
+ correct DDL visit method wasn't called, resulting
+ in "CREATE/DROP SEQUENCE" statements being
+ duplicated
+
+ .. change::
+ :tags: sqlite, bug
+ :tickets: 2364
+
+ the "name" of an FK constraint in SQLite
+ is reflected as "None", not "0" or other
+ integer value.
+ SQLite does not appear to support constraint
+ naming in any case.
+
+ .. change::
+ :tags: sqlite, bug
+ :tickets: 2368
+
+ sql.false() and sql.true() compile to
+ 0 and 1, respectively in sqlite
+
+ .. change::
+ :tags: sqlite, bug
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: bug, mysql
+ :tickets: 2376
+
+ fixed regexp that filters out warnings
+ for non-reflected "PARTITION" directives,
+ thanks to George Reilly
+
+ .. change::
+ :tags: mssql, bug
+ :tickets: 2340
+
+ 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.
+
+ .. change::
+ :tags: mssql, bug
+ :tickets: 2347
+
+ 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.
+
+ .. change::
+ :tags: oracle, bug
+ :tickets: 2388
+
+ Added ORA-03135 to the never ending
+ list of oracle "connection lost" errors
+
+ .. change::
+ :tags: core, bug
+ :tickets: 2379
+
+ 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.
+
+ .. change::
+ :tags: core, bug
+ :tickets: 2383
+
+ 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.
+
+ .. change::
+ :tags: bug, Py3K
+ :tickets: 2348
+
+ 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.
+
+ .. change::
+ :tags: examples, feature
+ :tickets: 2313
+
+ Simplified the versioning example
+ a bit to use a declarative mixin as well
+ as an event listener, instead of a metaclass +
+ SessionExtension.
+
+ .. change::
+ :tags: examples, bug
+ :tickets: 2346
+
+ Fixed large_collection.py to close the
+ session before dropping tables.
+
+ .. change::
+ :tags: orm, bug
+ :tickets: 2315
+
+ 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.
+
+ .. change::
+ :tags: orm, bug
+ :tickets: 2264
+
+ 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
+ case.
+
+ .. change::
+ :tags: orm, bug
+ :tickets: 2310
+
+ fixed inappropriate evaluation of user-mapped
+ object in a boolean context within query.get(). Also in 0.6.9.
+
+ .. change::
+ :tags: orm, bug
+ :tickets: 2304
+
+ Added missing comma to PASSIVE_RETURN_NEVER_SET
+ symbol
+
+ .. change::
+ :tags: orm, bug
+ :tickets: 1776
+
+ Cls.column.collate("some collation") now
+ works. Also in 0.6.9
+
+ .. change::
+ :tags: orm, bug
+ :tickets: 2309
+
+ 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.
+
+ .. change::
+ :tags: orm, bug
+ :tickets: 2309, 2308
+
+ The fix in 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.
+ Thanks to Scott Torborg for the test case here.
+
+ .. change::
+ :tags: orm, bug
+ :tickets: 2312
+
+ 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
+ base
+
+ .. change::
+ :tags: orm, bug
+ :tickets: 2312
+
+ 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.
+
+ .. change::
+ :tags: orm, bug
+ :tickets: 2316
+
+ 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.
+
+ .. change::
+ :tags: orm, bug
+ :tickets: 2297
+
+ Fixed the error formatting raised when
+ a tuple is inadvertently passed to session.query(). Also in 0.6.9.
+
+ .. change::
+ :tags: orm, bug
+ :tickets: 2328
+
+ 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.
+
+ .. change::
+ :tags: orm, bug
+ :tickets: 2339
+
+ __table_args__ can now be passed as
+ an empty tuple as well as an empty dict.. Thanks to Fayaz Yusuf Khan
+ for the patch.
+
+ .. change::
+ :tags: orm, bug
+ :tickets: 2325
+
+ 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.
+
+ .. change::
+ :tags: orm, feature
+ :tickets: 2345, 2238
+
+ polymorphic_on now accepts many
+ new kinds of values:
+
+ - standalone expressions that aren't
+ otherwise mapped
+ - column_property() objects
+ - string names of any column_property()
+ or attribute name of a mapped Column
+
+ The docs include an example using
+ the case() construct, which is likely to be
+ a common constructed used here. and part of
+
+ Standalone expressions in polymorphic_on
+ propagate to single-table inheritance
+ subclasses so that they are used in the
+ WHERE /JOIN clause to limit rows to that
+ subclass as is the usual behavior.
+
+ .. change::
+ :tags: orm, feature
+ :tickets: 2301
+
+ IdentitySet supports the - operator
+ as the same as difference(), handy when dealing
+ with Session.dirty etc.
+
+ .. change::
+ :tags: orm, feature
+ :tickets:
+
+ 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
+ its use.
+
+ .. change::
+ :tags: orm, bug
+ :tickets:
+
+ 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
+ function.
+
+ .. change::
+ :tags: bug, sql
+ :tickets: 2316, 2261
+
+ related to, made some
+ adjustments to the change from
+ 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"
+ anyway :).
+
+ .. change::
+ :tags: feature, sql
+ :tickets: 2166, 1944
+
+ 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.
+
+ .. change::
+ :tags: feature, sql
+ :tickets: 77
+
+ Added accessor to types called "python_type",
+ returns the rudimentary Python type object
+ for a particular TypeEngine instance, if known,
+ else raises NotImplementedError.
+
+ .. change::
+ :tags: bug, sql
+ :tickets: 2261, 2319
+
+ further tweak to the fix from,
+ 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.
+
+ .. change::
+ :tags: engine, bug
+ :tickets: 2317
+
+ 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.
+
+ .. change::
+ :tags: feature, schema
+ :tickets:
+
+ Added new support for remote "schemas":
+
+ .. change::
+ :tags: schema
+ :tickets:
+
+ MetaData() accepts "schema" and "quote_schema"
+ arguments, which will be applied to the same-named
+ arguments of a Table
+ or Sequence which leaves these at their default
+ of ``None``.
+
+ .. change::
+ :tags: schema
+ :tickets:
+
+ Sequence accepts "quote_schema" argument
+
+ .. change::
+ :tags: schema
+ :tickets:
+
+ tometadata() for Table will use the "schema"
+ of the incoming MetaData for the new Table
+ if the schema argument is explicitly "None"
+
+ .. change::
+ :tags: schema
+ :tickets:
+
+ Added CreateSchema and DropSchema DDL
+ constructs - these accept just the string
+ name of a schema and a "quote" flag.
+
+ .. change::
+ :tags: schema
+ :tickets:
+
+ 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 "schema".
+
+ .. change::
+ :tags: schema
+ :tickets: 1679
+
+ a "has_schema" method has been implemented
+ on dialect, but only works on Postgresql so far.
+ Courtesy Manlio Perillo.
+
+ .. change::
+ :tags: feature, schema
+ :tickets: 1410
+
+ 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.
+
+ .. change::
+ :tags: bug, schema
+ :tickets:
+
+ Fixed bug whereby TypeDecorator would
+ return a stale value for _type_affinity, when
+ using a TypeDecorator that "switches" types,
+ like the CHAR/UUID type.
+
+ .. change::
+ :tags: bug, schema
+ :tickets:
+
+ 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
+
+ .. change::
+ :tags: bug, schema
+ :tickets: 2305
+
+ the "name" of a column-level CHECK constraint,
+ if present, is now rendered in the CREATE TABLE
+ statement using "CONSTRAINT <name> CHECK <expression>".
+
+ .. change::
+ :tags: pyodbc, bug
+ :tickets: 2318
+
+ pyodbc-based dialects now parse the
+ pyodbc accurately as far as observed
+ pyodbc strings, including such gems
+ as "py3-3.0.1-beta4"
+
+ .. change::
+ :tags: postgresql, bug
+ :tickets: 2311
+
+ 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.
+
+ .. change::
+ :tags: postgresql, feature
+ :tickets:
+
+ 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"
+ scripts.
+
+ .. change::
+ :tags: mssql, feature
+ :tickets: 822
+
+ lifted the restriction on SAVEPOINT
+ for SQL Server. All tests pass using it,
+ it's not known if there are deeper issues
+ however.
+
+ .. change::
+ :tags: mssql, bug
+ :tickets: 2336
+
+ 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 :) )
+
+ .. change::
+ :tags: mssql, bug
+ :tickets: 2318
+
+ use new pyodbc version detection for
+ _need_decimal_fix option.
+
+ .. change::
+ :tags: mssql, bug
+ :tickets: 2343
+
+ 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.
+
+ .. change::
+ :tags: mssql, bug
+ :tickets: 2269
+
+ Decode incoming values when retrieving
+ list of index names and the names of columns
+ within those indexes.
+
+ .. change::
+ :tags: bug, mysql
+ :tickets:
+
+ Unicode adjustments allow latest pymysql
+ (post 0.4) to pass 100% on Python 2.
+
+ .. change::
+ :tags: ext, feature
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: ext, bug
+ :tickets:
+
+ the @compiles decorator raises an
+ informative error message when no "default"
+ compilation handler is present, rather
+ than KeyError.
+
+ .. change::
+ :tags: examples, bug
+ :tickets:
+
+ 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.
+
+.. changelog::
+ :version: 0.7.3
+ :released: Sun Oct 16 2011
+
+ .. change::
+ :tags: general
+ :tickets: 2279
+
+ 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. Also in 0.6.9.
+
+ .. change::
+ :tags: orm
+ :tickets: 2298
+
+ 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
+ of a mapped entity.
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets: 2241
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets: 2237
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets: 2282
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Fixed a variety of synonym()-related regressions
+ from 0.6:
+ - 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().
+
+ .. change::
+ :tags: orm
+ :tickets: 2287
+
+ Fixed bug whereby mapper.order_by attribute would
+ be ignored in the "inner" query within a
+ subquery eager load. .
+ Also in 0.6.9.
+
+ .. change::
+ :tags: orm
+ :tickets: 2267
+
+ Identity map .discard() uses dict.pop(,None)
+ internally instead of "del" to avoid KeyError/warning
+ during a non-determinate gc teardown
+
+ .. change::
+ :tags: orm
+ :tickets: 2253
+
+ Fixed regression in new composite rewrite where
+ deferred=True option failed due to missing
+ import
+
+ .. change::
+ :tags: orm
+ :tickets: 2248
+
+ Reinstated "comparator_factory" argument to
+ composite(), removed when 0.7 was released.
+
+ .. change::
+ :tags: orm
+ :tickets: 2247
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Query will convert an OFFSET of zero when
+ slicing into None, so that needless OFFSET
+ clauses are not invoked.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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
+ first mapper.
+
+ .. change::
+ :tags: orm
+ :tickets: 2260
+
+ Fixed bug whereby if __eq__() was
+ redefined, a relationship many-to-one lazyload
+ would hit the __eq__() and fail.
+ Does not apply to 0.6.9.
+
+ .. change::
+ :tags: orm
+ :tickets: 2196
+
+ 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.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ 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
+ already.
+
+ .. change::
+ :tags: orm
+ :tickets: 2281
+
+ 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.
+ This is accomplished by an extra check that the previous
+ "session_key" doesn't actually exist among the pool
+ of Sessions.
+
+ .. change::
+ :tags: orm
+ :tickets: 2239
+
+ New declarative features:
+ - __declare_last__() method, establishes an event
+ listener for the class method that will be called
+ when mappers are completed with the final "configure"
+ step.
+ - __abstract__ flag. The class will not be mapped
+ at all when this flag is present on the class.
+ - New helper classes ConcreteBase, AbstractConcreteBase.
+ Allow concrete mappings using declarative which automatically
+ set up the "polymorphic_union" when the "configure"
+ mapper step is invoked.
+ - The mapper itself has semi-private methods that allow
+ the "with_polymorphic" selectable to be assigned
+ to the mapper after it has already been configured.
+
+ .. change::
+ :tags: orm
+ :tickets: 2283
+
+ Declarative will warn when a subclass' base uses
+ @declared_attr for a regular column - this attribute
+ does not propagate to subclasses.
+
+ .. change::
+ :tags: orm
+ :tickets: 2280
+
+ The integer "id" used to link a mapped instance with
+ its owning Session is now generated by a sequence
+ generation function rather than id(Session), to
+ eliminate the possibility of recycled id() values
+ causing an incorrect result, no need to check that
+ object actually in the session.
+
+ .. change::
+ :tags: orm
+ :tickets: 2257
+
+ Behavioral improvement: empty
+ conjunctions such as and_() and or_() will be
+ flattened in the context of an enclosing conjunction,
+ i.e. and_(x, or_()) will produce 'X' and not 'X AND
+ ()'..
+
+ .. change::
+ :tags: orm
+ :tickets: 2261
+
+ Fixed bug regarding calculation of "from" list
+ for a select() element. The "from" calc is now
+ delayed, so that if the construct uses a Column
+ object that is not yet attached to a Table,
+ but is later associated with a Table, it generates
+ SQL using the table as a FROM. This change
+ impacted fairly deeply the mechanics of how
+ the FROM list as well as the "correlates" collection
+ is calculated, as some "clause adaption" schemes
+ (these are used very heavily in the ORM)
+ were relying upon the fact that the "froms"
+ collection would typically be cached before the
+ adaption completed. The rework allows it
+ such that the "froms" collection can be cleared
+ and re-generated at any time.
+
+ .. change::
+ :tags: orm
+ :tickets: 2270
+
+ Fixed bug whereby with_only_columns() method of
+ Select would fail if a selectable were passed.. Also in 0.6.9.
+
+ .. change::
+ :tags: schema
+ :tickets: 2284
+
+ Modified Column.copy() to use _constructor(),
+ which defaults to self.__class__, in order to
+ create the new object. This allows easier support
+ of subclassing Column.
+
+ .. change::
+ :tags: schema
+ :tickets: 2223
+
+ Added a slightly nicer __repr__() to SchemaItem
+ classes. Note the repr here can't fully support
+ the "repr is the constructor" idea since schema
+ items can be very deeply nested/cyclical, have
+ late initialization of some things, etc.
+
+ .. change::
+ :tags: engine
+ :tickets: 2254
+
+ The recreate() method in all pool classes uses
+ self.__class__ to get at the type of pool
+ to produce, in the case of subclassing. Note
+ there's no usual need to subclass pools.
+
+ .. change::
+ :tags: engine
+ :tickets: 2243
+
+ Improvement to multi-param statement logging,
+ long lists of bound parameter sets will be
+ compressed with an informative indicator
+ of the compression taking place. Exception
+ messages use the same improved formatting.
+
+ .. change::
+ :tags: engine
+ :tickets:
+
+ Added optional "sa_pool_key" argument to
+ pool.manage(dbapi).connect() so that serialization
+ of args is not necessary.
+
+ .. change::
+ :tags: engine
+ :tickets: 2286
+
+ The entry point resolution supported by
+ create_engine() now supports resolution of
+ individual DBAPI drivers on top of a built-in
+ or entry point-resolved dialect, using the
+ standard '+' notation - it's converted to
+ a '.' before being resolved as an entry
+ point.
+
+ .. change::
+ :tags: engine
+ :tickets: 2299
+
+ Added an exception catch + warning for the
+ "return unicode detection" step within connect,
+ allows databases that crash on NVARCHAR to
+ continue initializing, assuming no NVARCHAR
+ type implemented.
+
+ .. change::
+ :tags: types
+ :tickets: 2258
+
+ Extra keyword arguments to the base Float
+ type beyond "precision" and "asdecimal" are ignored;
+ added a deprecation warning here and additional
+ docs, related to
+
+ .. change::
+ :tags: sqlite
+ :tickets:
+
+ Ensured that the same ValueError is raised for
+ illegal date/time/datetime string parsed from
+ the database regardless of whether C
+ extensions are in use or not.
+
+ .. change::
+ :tags: postgresql
+ :tickets: 2290
+
+ Added "postgresql_using" argument to Index(), produces
+ USING clause to specify index implementation for
+ PG. . Thanks to Ryan P. Kelly for
+ the patch.
+
+ .. change::
+ :tags: postgresql
+ :tickets: 1839
+
+ Added client_encoding parameter to create_engine()
+ when the postgresql+psycopg2 dialect is used;
+ calls the psycopg2 set_client_encoding() method
+ with the value upon connect.
+
+ .. change::
+ :tags: postgresql
+ :tickets: 2291, 2141
+
+ Fixed bug related to whereby the
+ same modified index behavior in PG 9 affected
+ primary key reflection on a renamed column.. Also in 0.6.9.
+
+ .. change::
+ :tags: postgresql
+ :tickets: 2256
+
+ Reflection functions for Table, Sequence no longer
+ case insensitive. Names can be differ only in case
+ and will be correctly distinguished.
+
+ .. change::
+ :tags: postgresql
+ :tickets:
+
+ Use an atomic counter as the "random number"
+ source for server side cursor names;
+ conflicts have been reported in rare cases.
+
+ .. change::
+ :tags: postgresql
+ :tickets: 2249
+
+ Narrowed the assumption made when reflecting
+ a foreign-key referenced table with schema in
+ the current search path; an explicit schema will
+ be applied to the referenced table only if
+ it actually matches that of the referencing table,
+ which also has an explicit schema. Previously
+ it was assumed that "current" schema was synonymous
+ with the full search_path.
+
+ .. change::
+ :tags: mysql
+ :tickets: 2225
+
+ a CREATE TABLE will put the COLLATE option
+ after CHARSET, which appears to be part of
+ MySQL's arbitrary rules regarding if it will actually
+ work or not. Also in 0.6.9.
+
+ .. change::
+ :tags: mysql
+ :tickets: 2293
+
+ Added mysql_length parameter to Index construct,
+ specifies "length" for indexes.
+
+ .. change::
+ :tags: mssql
+ :tickets: 2273
+
+ Changes to attempt support of FreeTDS 0.91 with
+ Pyodbc. This includes that string binds are sent as
+ Python unicode objects when FreeTDS 0.91 is detected,
+ and a CAST(? AS NVARCHAR) is used when we detect
+ for a table. However, I'd continue
+ to characterize Pyodbc + FreeTDS 0.91 behavior as
+ pretty crappy, there are still many queries such
+ as used in reflection which cause a core dump on
+ Linux, and it is not really usable at all
+ on OSX, MemoryErrors abound and just plain broken
+ unicode support.
+
+ .. change::
+ :tags: mssql
+ :tickets: 2277
+
+ The behavior of =/!= when comparing a scalar select
+ to a value will no longer produce IN/NOT IN as of 0.8;
+ this behavior is a little too heavy handed (use in_() if
+ you want to emit IN) and now emits a deprecation warning.
+ To get the 0.8 behavior immediately and remove the warning,
+ a compiler recipe is given at
+ http://www.sqlalchemy.org/docs/07/dialects/mssql.html#scalar-select-comparisons
+ to override the behavior of visit_binary().
+
+ .. change::
+ :tags: mssql
+ :tickets: 2222
+
+ "0" is accepted as an argument for limit() which
+ will produce "TOP 0".
+
+ .. change::
+ :tags: oracle
+ :tickets: 2272
+
+ Fixed ReturningResultProxy for zxjdbc dialect.. Regression from 0.6.
+
+ .. change::
+ :tags: oracle
+ :tickets: 2252
+
+ The String type now generates VARCHAR2 on Oracle
+ which is recommended as the default VARCHAR.
+ Added an explicit VARCHAR2 and NVARCHAR2 to the Oracle
+ dialect as well. Using NVARCHAR still generates
+ "NVARCHAR2" - there is no "NVARCHAR" on Oracle -
+ this remains a slight breakage of the "uppercase types
+ always give exactly that" policy. VARCHAR still
+ generates "VARCHAR", keeping with the policy. If
+ Oracle were to ever define "VARCHAR" as something
+ different as they claim (IMHO this will never happen),
+ the type would be available.
+
+ .. change::
+ :tags: ext
+ :tickets: 2262
+
+ SQLSoup will not be included in version 0.8
+ of SQLAlchemy; while useful, we would like to
+ keep SQLAlchemy itself focused on one ORM
+ usage paradigm. SQLSoup will hopefully
+ soon be superseded by a third party
+ project.
+
+ .. change::
+ :tags: ext
+ :tickets: 2236
+
+ Added local_attr, remote_attr, attr accessors
+ to AssociationProxy, providing quick access
+ to the proxied attributes at the class
+ level.
+
+ .. change::
+ :tags: ext
+ :tickets: 2275
+
+ Changed the update() method on association proxy
+ dictionary to use a duck typing approach, i.e.
+ checks for "keys", to discern between update({})
+ and update((a, b)). Previously, passing a
+ dictionary that had tuples as keys would be misinterpreted
+ as a sequence.
+
+ .. change::
+ :tags: examples
+ :tickets: 2266
+
+ Adjusted dictlike-polymorphic.py example
+ to apply the CAST such that it works on
+ PG, other databases.
+ Also in 0.6.9.
+
+.. changelog::
+ :version: 0.7.2
+ :released: Sun Jul 31 2011
+
+ .. change::
+ :tags: orm
+ :tickets: 2213
+
+ Feature enhancement: joined and subquery
+ loading will now traverse already-present related
+ objects and collections in search of unpopulated
+ attributes throughout the scope of the eager load
+ being defined, so that the eager loading that is
+ specified via mappings or query options
+ unconditionally takes place for the full depth,
+ populating whatever is not already populated.
+ Previously, this traversal would stop if a related
+ object or collection were already present leading
+ to inconsistent behavior (though would save on
+ loads/cycles for an already-loaded graph). For a
+ subqueryload, this means that the additional
+ SELECT statements emitted by subqueryload will
+ invoke unconditionally, no matter how much of the
+ existing graph is already present (hence the
+ controversy). The previous behavior of "stopping"
+ is still in effect when a query is the result of
+ an attribute-initiated lazyload, as otherwise an
+ "N+1" style of collection iteration can become
+ needlessly expensive when the same related object
+ is encountered repeatedly. There's also an
+ as-yet-not-public generative Query method
+ _with_invoke_all_eagers()
+ which selects old/new behavior
+
+ .. change::
+ :tags: orm
+ :tickets: 2195
+
+ A rework of "replacement traversal" within
+ the ORM as it alters selectables to be against
+ aliases of things (i.e. clause adaption) includes
+ a fix for multiply-nested any()/has() constructs
+ against a joined table structure.
+
+ .. change::
+ :tags: orm
+ :tickets: 2234
+
+ Fixed bug where query.join() + aliased=True
+ from a joined-inh structure to itself on
+ relationship() with join condition on the child
+ table would convert the lead entity into the
+ joined one inappropriately.
+ Also in 0.6.9.
+
+ .. change::
+ :tags: orm
+ :tickets: 2205
+
+ Fixed regression from 0.6 where Session.add()
+ against an object which contained None in a
+ collection would raise an internal exception.
+ Reverted this to 0.6's behavior which is to
+ accept the None but obviously nothing is
+ persisted. Ideally, collections with None
+ present or on append() should at least emit a
+ warning, which is being considered for 0.8.
+
+ .. change::
+ :tags: orm
+ :tickets: 2191
+
+ Load of a deferred() attribute on an object
+ where row can't be located raises
+ ObjectDeletedError instead of failing later
+ on; improved the message in ObjectDeletedError
+ to include other conditions besides a simple
+ "delete".
+
+ .. change::
+ :tags: orm
+ :tickets: 2224
+
+ Fixed regression from 0.6 where a get history
+ operation on some relationship() based attributes
+ would fail when a lazyload would emit; this could
+ trigger within a flush() under certain conditions. Thanks to the user who submitted
+ the great test for this.
+
+ .. change::
+ :tags: orm
+ :tickets: 2228
+
+ Fixed bug apparent only in Python 3 whereby
+ sorting of persistent + pending objects during
+ flush would produce an illegal comparison,
+ if the persistent object primary key
+ is not a single integer.
+ Also in 0.6.9
+
+ .. change::
+ :tags: orm
+ :tickets: 2197
+
+ Fixed bug whereby the source clause
+ used by query.join() would be inconsistent
+ if against a column expression that combined
+ multiple entities together.
+ Also in 0.6.9
+
+ .. change::
+ :tags: orm
+ :tickets: 2215
+
+ Fixed bug whereby if a mapped class
+ redefined __hash__() or __eq__() to something
+ non-standard, which is a supported use case
+ as SQLA should never consult these,
+ the methods would be consulted if the class
+ was part of a "composite" (i.e. non-single-entity)
+ result set.
+ Also in 0.6.9.
+
+ .. change::
+ :tags: orm
+ :tickets: 2240
+
+ Added public attribute ".validators" to
+ Mapper, an immutable dictionary view of
+ all attributes that have been decorated
+ with the @validates decorator. courtesy Stefano Fontanelli
+
+ .. change::
+ :tags: orm
+ :tickets: 2188
+
+ Fixed subtle bug that caused SQL to blow
+ up if: column_property() against subquery +
+ joinedload + LIMIT + order by the column
+ property() occurred. .
+ Also in 0.6.9
+
+ .. change::
+ :tags: orm
+ :tickets: 2207
+
+ The join condition produced by with_parent
+ as well as when using a "dynamic" relationship
+ against a parent will generate unique
+ bindparams, rather than incorrectly repeating
+ the same bindparam. .
+ Also in 0.6.9.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Added the same "columns-only" check to
+ mapper.polymorphic_on as used when
+ receiving user arguments to
+ relationship.order_by, foreign_keys,
+ remote_side, etc.
+
+ .. change::
+ :tags: orm
+ :tickets: 2190
+
+ Fixed bug whereby comparison of column
+ expression to a Query() would not call
+ as_scalar() on the underlying SELECT
+ statement to produce a scalar subquery,
+ in the way that occurs if you called
+ it on Query().subquery().
+
+ .. change::
+ :tags: orm
+ :tickets: 2194
+
+ Fixed declarative bug where a class inheriting
+ from a superclass of the same name would fail
+ due to an unnecessary lookup of the name
+ in the _decl_class_registry.
+
+ .. change::
+ :tags: orm
+ :tickets: 2199
+
+ Repaired the "no statement condition"
+ assertion in Query which would attempt
+ to raise if a generative method were called
+ after from_statement() were called.. Also in 0.6.9.
+
+ .. change::
+ :tags: sql
+ :tickets: 2188
+
+ Fixed two subtle bugs involving column
+ correspondence in a selectable,
+ one with the same labeled subquery repeated, the other
+ when the label has been "grouped" and
+ loses itself. Affects.
+
+ .. change::
+ :tags: schema
+ :tickets: 2187
+
+ New feature: with_variant() method on
+ all types. Produces an instance of Variant(),
+ a special TypeDecorator which will select
+ the usage of a different type based on the
+ dialect in use.
+
+ .. change::
+ :tags: schema
+ :tickets:
+
+ Added an informative error message when
+ ForeignKeyConstraint refers to a column name in
+ the parent that is not found. Also in 0.6.9.
+
+ .. change::
+ :tags: schema
+ :tickets: 2206
+
+ Fixed bug whereby adaptation of old append_ddl_listener()
+ function was passing unexpected **kw through
+ to the Table event. Table gets no kws, the MetaData
+ event in 0.6 would get "tables=somecollection",
+ this behavior is preserved.
+
+ .. change::
+ :tags: schema
+ :tickets:
+
+ Fixed bug where "autoincrement" detection on
+ Table would fail if the type had no "affinity"
+ value, in particular this would occur when using
+ the UUID example on the site that uses TypeEngine
+ as the "impl".
+
+ .. change::
+ :tags: schema
+ :tickets: 2209
+
+ Added an improved repr() to TypeEngine objects
+ that will only display constructor args which
+ are positional or kwargs that deviate
+ from the default.
+
+ .. change::
+ :tags: engine
+ :tickets:
+
+ Context manager provided by Connection.begin()
+ will issue rollback() if the commit() fails,
+ not just if an exception occurs.
+
+ .. change::
+ :tags: engine
+ :tickets: 1682
+
+ Use urllib.parse_qsl() in Python 2.6 and above,
+ no deprecation warning about cgi.parse_qsl()
+
+ .. change::
+ :tags: engine
+ :tickets:
+
+ Added mixin class sqlalchemy.ext.DontWrapMixin.
+ User-defined exceptions of this type are never
+ wrapped in StatementException when they
+ occur in the context of a statement
+ execution.
+
+ .. change::
+ :tags: engine
+ :tickets:
+
+ StatementException wrapping will display the
+ original exception class in the message.
+
+ .. change::
+ :tags: engine
+ :tickets: 2201
+
+ Failures on connect which raise dbapi.Error
+ will forward the error to dialect.is_disconnect()
+ and set the "connection_invalidated" flag if
+ the dialect knows this to be a potentially
+ "retryable" condition. Only Oracle ORA-01033
+ implemented for now.
+
+ .. change::
+ :tags: sqlite
+ :tickets: 2189
+
+ SQLite dialect no longer strips quotes
+ off of reflected default value, allowing
+ a round trip CREATE TABLE to work.
+ This is consistent with other dialects
+ that also maintain the exact form of
+ the default.
+
+ .. change::
+ :tags: postgresql
+ :tickets: 2198
+
+ Added new "postgresql_ops" argument to
+ Index, allows specification of PostgreSQL
+ operator classes for indexed columns. Courtesy Filip Zyzniewski.
+
+ .. change::
+ :tags: mysql
+ :tickets: 2186
+
+ Fixed OurSQL dialect to use ansi-neutral
+ quote symbol "'" for XA commands instead
+ of '"'. . Also in 0.6.9.
+
+ .. change::
+ :tags: mssql
+ :tickets:
+
+ Adjusted the pyodbc dialect such that bound
+ values are passed as bytes and not unicode
+ if the "Easysoft" unix drivers are detected.
+ This is the same behavior as occurs with
+ FreeTDS. Easysoft appears to segfault
+ if Python unicodes are passed under
+ certain circumstances.
+
+ .. change::
+ :tags: oracle
+ :tickets: 2200
+
+ Added ORA-00028 to disconnect codes, use
+ cx_oracle _Error.code to get at the code,. Also in 0.6.9.
+
+ .. change::
+ :tags: oracle
+ :tickets: 2201
+
+ Added ORA-01033 to disconnect codes, which
+ can be caught during a connection
+ event.
+
+ .. change::
+ :tags: oracle
+ :tickets: 2220
+
+ repaired the oracle.RAW type which did not
+ generate the correct DDL.
+ Also in 0.6.9.
+
+ .. change::
+ :tags: oracle
+ :tickets: 2212
+
+ added CURRENT to reserved word list. Also in 0.6.9.
+
+ .. change::
+ :tags: ext
+ :tickets:
+
+ Fixed bug in the mutable extension whereby
+ if the same type were used twice in one
+ mapping, the attributes beyond the first
+ would not get instrumented.
+
+ .. change::
+ :tags: ext
+ :tickets:
+
+ Fixed bug in the mutable extension whereby
+ if None or a non-corresponding type were set,
+ an error would be raised. None is now accepted
+ which assigns None to all attributes,
+ illegal values raise ValueError.
+
+ .. change::
+ :tags: examples
+ :tickets:
+
+ Repaired the examples/versioning test runner
+ to not rely upon SQLAlchemy test libs,
+ nosetests must be run from within
+ examples/versioning to get around setup.cfg
+ breaking it.
+
+ .. change::
+ :tags: examples
+ :tickets:
+
+ Tweak to examples/versioning to pick the
+ correct foreign key in a multi-level
+ inheritance situation.
+
+ .. change::
+ :tags: examples
+ :tickets:
+
+ Fixed the attribute shard example to check
+ for bind param callable correctly in 0.7
+ style.
+
+.. changelog::
+ :version: 0.7.1
+ :released: Sun Jun 05 2011
+
+ .. change::
+ :tags: general
+ :tickets: 2184
+
+ Added a workaround for Python bug 7511 where
+ failure of C extension build does not
+ raise an appropriate exception on Windows 64
+ bit + VC express
+
+ .. change::
+ :tags: orm
+ :tickets: 1912
+
+ "delete-orphan" cascade is now allowed on
+ self-referential relationships - this since
+ SQLA 0.7 no longer enforces "parent with no
+ child" at the ORM level; this check is left
+ up to foreign key nullability.
+ Related to
+
+ .. change::
+ :tags: orm
+ :tickets: 2180
+
+ Repaired new "mutable" extension to propagate
+ events to subclasses correctly; don't
+ create multiple event listeners for
+ subclasses either.
+
+ .. change::
+ :tags: orm
+ :tickets: 2170
+
+ Modify the text of the message which occurs
+ when the "identity" key isn't detected on
+ flush, to include the common cause that
+ the Column isn't set up to detect
+ auto-increment correctly;.
+ Also in 0.6.8.
+
+ .. change::
+ :tags: orm
+ :tickets: 2182
+
+ Fixed bug where transaction-level "deleted"
+ collection wouldn't be cleared of expunged
+ states, raising an error if they later
+ became transient.
+ Also in 0.6.8.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Fixed bug whereby metadata.reflect(bind)
+ would close a Connection passed as a
+ bind argument. Regression from 0.6.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Streamlined the process by which a Select
+ determines what's in it's '.c' collection.
+ Behaves identically, except that a
+ raw ClauseList() passed to select([])
+ (which is not a documented case anyway) will
+ now be expanded into its individual column
+ elements instead of being ignored.
+
+ .. change::
+ :tags: engine
+ :tickets:
+
+ Deprecate schema/SQL-oriented methods on
+ Connection/Engine that were never well known
+ and are redundant: reflecttable(), create(),
+ drop(), text(), engine.func
+
+ .. change::
+ :tags: engine
+ :tickets: 2178
+
+ Adjusted the __contains__() method of
+ a RowProxy result row such that no exception
+ throw is generated internally;
+ NoSuchColumnError() also will generate its
+ message regardless of whether or not the column
+ construct can be coerced to a string.. Also in 0.6.8.
+
+ .. change::
+ :tags: sqlite
+ :tickets: 2173
+
+ Accept None from cursor.fetchone() when
+ "PRAGMA read_uncommitted" is called to determine
+ current isolation mode at connect time and
+ default to SERIALIZABLE; this to support SQLite
+ versions pre-3.3.0 that did not have this
+ feature.
+
+ .. change::
+ :tags: postgresql
+ :tickets: 2175
+
+ Some unit test fixes regarding numeric arrays,
+ MATCH operator. A potential floating-point
+ inaccuracy issue was fixed, and certain tests
+ of the MATCH operator only execute within an
+ EN-oriented locale for now. .
+ Also in 0.6.8.
+
+ .. change::
+ :tags: mysql
+ :tickets:
+
+ Unit tests pass 100% on MySQL installed
+ on windows.
+
+ .. change::
+ :tags: mysql
+ :tickets: 2181
+
+ Removed the "adjust casing" step that would
+ fail when reflecting a table on MySQL
+ on windows with a mixed case name. After some
+ experimenting with a windows MySQL server, it's
+ been determined that this step wasn't really
+ helping the situation much; MySQL does not return
+ FK names with proper casing on non-windows
+ platforms either, and removing the step at
+ least allows the reflection to act more like
+ it does on other OSes. A warning here
+ has been considered but its difficult to
+ determine under what conditions such a warning
+ can be raised, so punted on that for now -
+ added some docs instead.
+
+ .. change::
+ :tags: mysql
+ :tickets:
+
+ supports_sane_rowcount will be set to False
+ if using MySQLdb and the DBAPI doesn't provide
+ the constants.CLIENT module.
+
+.. changelog::
+ :version: 0.7.0
+ :released: Fri May 20 2011
+
+ .. change::
+ :tags: mysql
+ :tickets:
+
+ This section documents those changes from 0.7b4
+ to 0.7.0. For an overview of what's new in
+ SQLAlchemy 0.7, see
+ http://www.sqlalchemy.org/trac/wiki/07Migration
+
+ .. change::
+ :tags: orm
+ :tickets: 2069
+
+ Fixed regression introduced in 0.7b4 (!) whereby
+ query.options(someoption("nonexistent name")) would
+ fail to raise an error. Also added additional
+ error catching for cases where the option would
+ try to build off a column-based element, further
+ fixed up some of the error messages tailored
+ in
+
+ .. change::
+ :tags: orm
+ :tickets: 2162
+
+ query.count() emits "count(*)" instead of
+ "count(1)".
+
+ .. change::
+ :tags: orm
+ :tickets: 2155
+
+ Fine tuning of Query clause adaptation when
+ from_self(), union(), or other "select from
+ myself" operation, such that plain SQL expression
+ elements added to filter(), order_by() etc.
+ which are present in the nested "from myself"
+ query *will* be adapted in the same way an ORM
+ expression element will, since these
+ elements are otherwise not easily accessible.
+
+ .. change::
+ :tags: orm
+ :tickets: 2149
+
+ Fixed bug where determination of "self referential"
+ relationship would fail with no workaround
+ for joined-inh subclass related to itself,
+ or joined-inh subclass related to a subclass
+ of that with no cols in the sub-sub class
+ in the join condition.
+ Also in 0.6.8.
+
+ .. change::
+ :tags: orm
+ :tickets: 2153
+
+ mapper() will ignore non-configured foreign keys
+ to unrelated tables when determining inherit
+ condition between parent and child class,
+ but will raise as usual for unresolved
+ columns and table names regarding the inherited
+ table. This is an enhanced generalization of
+ behavior that was already applied to declarative
+ previously. 0.6.8 has a more
+ conservative version of this which doesn't
+ fundamentally alter how join conditions
+ are determined.
+
+ .. change::
+ :tags: orm
+ :tickets: 2144
+
+ It is an error to call query.get() when the
+ given entity is not a single, full class
+ entity or mapper (i.e. a column). This is
+ a deprecation warning in 0.6.8.
+
+ .. change::
+ :tags: orm
+ :tickets: 2148
+
+ Fixed a potential KeyError which under some
+ circumstances could occur with the identity
+ map, part of
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ added Query.with_session() method, switches
+ Query to use a different session.
+
+ .. change::
+ :tags: orm
+ :tickets: 2131
+
+ horizontal shard query should use execution
+ options per connection as per
+
+ .. change::
+ :tags: orm
+ :tickets: 2151
+
+ a non_primary mapper will inherit the _identity_class
+ of the primary mapper. This so that a non_primary
+ established against a class that's normally in an
+ inheritance mapping will produce results that are
+ identity-map compatible with that of the primary
+ mapper (also in 0.6.8)
+
+ .. change::
+ :tags: orm
+ :tickets: 2163
+
+ Fixed the error message emitted for "can't
+ execute syncrule for destination column 'q';
+ mapper 'X' does not map this column" to
+ reference the correct mapper. .
+ Also in 0.6.8.
+
+ .. change::
+ :tags: orm
+ :tickets: 1502
+
+ polymorphic_union() gets a "cast_nulls" option,
+ disables the usage of CAST when it renders
+ the labeled NULL columns.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ polymorphic_union() renders the columns in their
+ original table order, as according to the first
+ table/selectable in the list of polymorphic
+ unions in which they appear. (which is itself
+ an unordered mapping unless you pass an OrderedDict).
+
+ .. change::
+ :tags: orm
+ :tickets: 2171
+
+ Fixed bug whereby mapper mapped to an anonymous
+ alias would fail if logging were used, due to
+ unescaped % sign in the alias name.
+ Also in 0.6.8.
+
+ .. change::
+ :tags: sql
+ :tickets: 2167
+
+ Fixed bug whereby nesting a label of a select()
+ with another label in it would produce incorrect
+ exported columns. Among other things this would
+ break an ORM column_property() mapping against
+ another column_property(). .
+ Also in 0.6.8
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Changed the handling in determination of join
+ conditions such that foreign key errors are
+ only considered between the two given tables.
+ That is, t1.join(t2) will report FK errors
+ that involve 't1' or 't2', but anything
+ involving 't3' will be skipped. This affects
+ join(), as well as ORM relationship and
+ inherit condition logic.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Some improvements to error handling inside
+ of the execute procedure to ensure auto-close
+ connections are really closed when very
+ unusual DBAPI errors occur.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ metadata.reflect() and reflection.Inspector()
+ had some reliance on GC to close connections
+ which were internally procured, fixed this.
+
+ .. change::
+ :tags: sql
+ :tickets: 2140
+
+ Added explicit check for when Column .name
+ is assigned as blank string
+
+ .. change::
+ :tags: sql
+ :tickets: 2147
+
+ Fixed bug whereby if FetchedValue was passed
+ to column server_onupdate, it would not
+ have its parent "column" assigned, added
+ test coverage for all column default assignment
+ patterns. also in 0.6.8
+
+ .. change::
+ :tags: postgresql
+ :tickets:
+
+ Fixed the psycopg2_version parsing in the
+ psycopg2 dialect.
+
+ .. change::
+ :tags: postgresql
+ :tickets: 2141
+
+ Fixed bug affecting PG 9 whereby index reflection
+ would fail if against a column whose name
+ had changed. . Also in 0.6.8.
+
+ .. change::
+ :tags: mssql
+ :tickets: 2169
+
+ Fixed bug in MSSQL dialect whereby the aliasing
+ applied to a schema-qualified table would leak
+ into enclosing select statements.
+ Also in 0.6.8.
+
+ .. change::
+ :tags: documentation
+ :tickets: 2152
+
+ Removed the usage of the "collections.MutableMapping"
+ abc from the ext.mutable docs as it was being used
+ incorrectly and makes the example more difficult
+ to understand in any case.
+
+ .. change::
+ :tags: examples
+ :tickets:
+
+ removed the ancient "polymorphic association"
+ examples and replaced with an updated set of
+ examples that use declarative mixins,
+ "generic_associations". Each presents an alternative
+ table layout.
+
+ .. change::
+ :tags: ext
+ :tickets: 2143
+
+ Fixed bugs in sqlalchemy.ext.mutable extension where
+ `None` was not appropriately handled, replacement
+ events were not appropriately handled.
+
+.. changelog::
+ :version: 0.7.0b4
+ :released: Sun Apr 17 2011
+
+ .. change::
+ :tags: general
+ :tickets:
+
+ Changes to the format of CHANGES, this file.
+ The format changes have been applied to
+ the 0.7 releases.
+
+ .. change::
+ :tags: general
+ :tickets:
+
+ The "-declarative" changes will now be listed
+ directly under the "-orm" section, as these
+ are closely related.
+
+ .. change::
+ :tags: general
+ :tickets:
+
+ The 0.5 series changes have been moved to
+ the file CHANGES_PRE_06 which replaces
+ CHANGES_PRE_05.
+
+ .. change::
+ :tags: general
+ :tickets:
+
+ The changelog for 0.6.7 and subsequent within
+ the 0.6 series is now listed only in the
+ CHANGES file within the 0.6 branch.
+ In the 0.7 CHANGES file (i.e. this file), all the
+ 0.6 changes are listed inline within the 0.7
+ section in which they were also applied
+ (since all 0.6 changes are in 0.7 as well).
+ Changes that apply to an 0.6 version here
+ are noted as are if any differences in
+ implementation/behavior are present.
+
+ .. change::
+ :tags: orm
+ :tickets: 2122
+
+ Some fixes to "evaulate" and "fetch" evaluation
+ when query.update(), query.delete() are called.
+ The retrieval of records is done after autoflush
+ in all cases, and before update/delete is
+ emitted, guarding against unflushed data present
+ as well as expired objects failing during
+ the evaluation.
+
+ .. change::
+ :tags: orm
+ :tickets: 2063
+
+ Reworded the exception raised when a flush
+ is attempted of a subclass that is not polymorphic
+ against the supertype.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Still more wording adjustments when a query option
+ can't find the target entity. Explain that the
+ path must be from one of the root entities.
+
+ .. change::
+ :tags: orm
+ :tickets: 2123
+
+ Some fixes to the state handling regarding
+ backrefs, typically when autoflush=False, where
+ the back-referenced collection wouldn't
+ properly handle add/removes with no net
+ change. Thanks to Richard Murri for the
+ test case + patch.
+ (also in 0.6.7).
+
+ .. change::
+ :tags: orm
+ :tickets: 2127
+
+ Added checks inside the UOW to detect the unusual
+ condition of being asked to UPDATE or DELETE
+ on a primary key value that contains NULL
+ in it.
+
+ .. change::
+ :tags: orm
+ :tickets: 2127
+
+ Some refinements to attribute history. More
+ changes are pending possibly in 0.8, but
+ for now history has been modified such that
+ scalar history doesn't have a "side effect"
+ of populating None for a non-present value.
+ This allows a slightly better ability to
+ distinguish between a None set and no actual
+ change, affects as well.
+
+ .. change::
+ :tags: orm
+ :tickets: 2130
+
+ a "having" clause would be copied from the
+ inside to the outside query if from_self()
+ were used; in particular this would break
+ an 0.7 style count() query.
+ (also in 0.6.7)
+
+ .. change::
+ :tags: orm
+ :tickets: 2131
+
+ the Query.execution_options() method now passes
+ those options to the Connection rather than
+ the SELECT statement, so that all available
+ options including isolation level and
+ compiled cache may be used.
+
+ .. change::
+ :tags: sql
+ :tickets: 2131
+
+ The "compiled_cache" execution option now raises
+ an error when passed to a SELECT statement
+ rather than a Connection. Previously it was
+ being ignored entirely. We may look into
+ having this option work on a per-statement
+ level at some point.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Restored the "catchall" constructor on the base
+ TypeEngine class, with a deprecation warning.
+ This so that code which does something like
+ Integer(11) still succeeds.
+
+ .. change::
+ :tags: sql
+ :tickets: 2104
+
+ Fixed regression whereby MetaData() coming
+ back from unpickling did not keep track of
+ new things it keeps track of now, i.e.
+ collection of Sequence objects, list
+ of schema names.
+
+ .. change::
+ :tags: sql
+ :tickets: 2116
+
+ The limit/offset keywords to select() as well
+ as the value passed to select.limit()/offset()
+ will be coerced to integer.
+ (also in 0.6.7)
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ fixed bug where "from" clause gathering from an
+ over() clause would be an itertools.chain() and
+ not a list, causing "can only concatenate list"
+ TypeError when combined with other clauses.
+
+ .. change::
+ :tags: sql
+ :tickets: 2134
+
+ Fixed incorrect usage of "," in over() clause
+ being placed between the "partition" and "order by"
+ clauses.
+
+ .. change::
+ :tags: sql
+ :tickets: 2105
+
+ Before/after attach events for PrimaryKeyConstraint
+ now function, tests added for before/after events
+ on all constraint types.
+
+ .. change::
+ :tags: sql
+ :tickets: 2117
+
+ Added explicit true()/false() constructs to expression
+ lib - coercion rules will intercept "False"/"True"
+ into these constructs. In 0.6, the constructs were
+ typically converted straight to string, which was
+ no longer accepted in 0.7.
+
+ .. change::
+ :tags: engine
+ :tickets: 2129
+
+ The C extension is now enabled by default on CPython
+ 2.x with a fallback to pure python if it fails to
+ compile.
+
+ .. change::
+ :tags: schema
+ :tickets: 2109
+
+ The 'useexisting' flag on Table has been superceded
+ by a new pair of flags 'keep_existing' and
+ 'extend_existing'. 'extend_existing' is equivalent
+ to 'useexisting' - the existing Table is returned,
+ and additional constructor elements are added.
+ With 'keep_existing', the existing Table is returned,
+ but additional constructor elements are not added -
+ these elements are only applied when the Table
+ is newly created.
+
+ .. change::
+ :tags: types
+ :tickets: 2081
+
+ REAL has been added to the core types. Supported
+ by Postgresql, SQL Server, MySQL, SQLite. Note
+ that the SQL Server and MySQL versions, which
+ add extra arguments, are also still available
+ from those dialects.
+
+ .. change::
+ :tags: types
+ :tickets: 2106
+
+ Added @event.listens_for() decorator, given
+ target + event name, applies the decorated
+ function as a listener.
+
+ .. change::
+ :tags: pool
+ :tickets: 2103
+
+ AssertionPool now stores the traceback indicating
+ where the currently checked out connection was
+ acquired; this traceback is reported within
+ the assertion raised upon a second concurrent
+ checkout; courtesy Gunnlaugur Briem
+
+ .. change::
+ :tags: pool
+ :tickets:
+
+ The "pool.manage" feature doesn't use pickle
+ anymore to hash the arguments for each pool.
+
+ .. change::
+ :tags: sqlite
+ :tickets: 2115
+
+ Fixed bug where reflection of foreign key
+ created as "REFERENCES <tablename>" without
+ col name would fail.
+ (also in 0.6.7)
+
+ .. change::
+ :tags: postgresql
+ :tickets:
+
+ Psycopg2 for Python 3 is now supported.
+
+ .. change::
+ :tags: postgresql
+ :tickets: 2132
+
+ Fixed support for precision numerics when using
+ pg8000.
+
+ .. change::
+ :tags: oracle
+ :tickets: 2100
+
+ Using column names that would require quotes
+ for the column itself or for a name-generated
+ bind parameter, such as names with special
+ characters, underscores, non-ascii characters,
+ now properly translate bind parameter keys when
+ talking to cx_oracle. (Also
+ in 0.6.7)
+
+ .. change::
+ :tags: oracle
+ :tickets: 2116
+
+ Oracle dialect adds use_binds_for_limits=False
+ create_engine() flag, will render the LIMIT/OFFSET
+ values inline instead of as binds, reported to
+ modify the execution plan used by Oracle. (Also in 0.6.7)
+
+ .. change::
+ :tags: documentation
+ :tickets: 2029
+
+ Documented SQLite DATE/TIME/DATETIME types. (also in 0.6.7)
+
+ .. change::
+ :tags: documentation
+ :tickets: 2118
+
+ Fixed mutable extension docs to show the
+ correct type-association methods.
+
+.. changelog::
+ :version: 0.7.0b3
+ :released: Sun Mar 20 2011
+
+ .. change::
+ :tags: general
+ :tickets:
+
+ Lots of fixes to unit tests when run under Pypy
+ (courtesy Alex Gaynor).
+
+ .. change::
+ :tags: orm
+ :tickets: 2093
+
+ Changed the underlying approach to query.count().
+ query.count() is now in all cases exactly:
+
+ query.
+ from_self(func.count(literal_column('1'))).
+ scalar()
+
+ That is, "select count(1) from (<full query>)".
+ This produces a subquery in all cases, but
+ vastly simplifies all the guessing count()
+ tried to do previously, which would still
+ fail in many scenarios particularly when
+ joined table inheritance and other joins
+ were involved. If the subquery produced
+ for an otherwise very simple count is really
+ an issue, use query(func.count()) as an
+ optimization.
+
+ .. change::
+ :tags: orm
+ :tickets: 2087
+
+ some changes to the identity map regarding
+ rare weakref callbacks during iterations.
+ The mutex has been removed as it apparently
+ can cause a reentrant (i.e. in one thread) deadlock,
+ perhaps when gc collects objects at the point of
+ iteration in order to gain more memory. It is hoped
+ that "dictionary changed during iteration" will
+ be exceedingly rare as iteration methods internally
+ acquire the full list of objects in a single values()
+ call. Note 0.6.7 has a more conservative fix here
+ which still keeps the mutex in place.
+
+ .. change::
+ :tags: orm
+ :tickets: 2082
+
+ A tweak to the unit of work causes it to order
+ the flush along relationship() dependencies even if
+ the given objects don't have any inter-attribute
+ references in memory, which was the behavior in
+ 0.5 and earlier, so a flush of Parent/Child with
+ only foreign key/primary key set will succeed.
+ This while still maintaining 0.6 and above's not
+ generating a ton of useless internal dependency
+ structures within the flush that don't correspond
+ to state actually within the current flush.
+
+ .. change::
+ :tags: orm
+ :tickets: 2069
+
+ Improvements to the error messages emitted when
+ querying against column-only entities in conjunction
+ with (typically incorrectly) using loader options,
+ where the parent entity is not fully present.
+
+ .. change::
+ :tags: orm
+ :tickets: 2098
+
+ Fixed bug in query.options() whereby a path
+ applied to a lazyload using string keys could
+ overlap a same named attribute on the wrong
+ entity. Note 0.6.7 has a more conservative fix
+ to this.
+
+ .. change::
+ :tags: declarative
+ :tickets: 2091
+
+ Arguments in __mapper_args__ that aren't "hashable"
+ aren't mistaken for always-hashable, possibly-column
+ arguments. (also in 0.6.7)
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Added a fully descriptive error message for the
+ case where Column is subclassed and _make_proxy()
+ fails to make a copy due to TypeError on the
+ constructor. The method _constructor should
+ be implemented in this case.
+
+ .. change::
+ :tags: sql
+ :tickets: 2095
+
+ Added new event "column_reflect" for Table objects.
+ Receives the info dictionary about a Column before
+ the object is generated within reflection, and allows
+ modification to the dictionary for control over
+ most aspects of the resulting Column including
+ key, name, type, info dictionary.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ To help with the "column_reflect" event being used
+ with specific Table objects instead of all instances
+ of Table, listeners can be added to a Table object
+ inline with its construction using a new argument
+ "listeners", a list of tuples of the form
+ (<eventname>, <fn>), which are applied to the Table
+ before the reflection process begins.
+
+ .. change::
+ :tags: sql
+ :tickets: 2085
+
+ Added new generic function "next_value()", accepts
+ a Sequence object as its argument and renders the
+ appropriate "next value" generation string on the
+ target platform, if supported. Also provides
+ ".next_value()" method on Sequence itself.
+
+ .. change::
+ :tags: sql
+ :tickets: 2084
+
+ func.next_value() or other SQL expression can
+ be embedded directly into an insert() construct,
+ and if implicit or explicit "returning" is used
+ in conjunction with a primary key column,
+ the newly generated value will be present in
+ result.inserted_primary_key.
+
+ .. change::
+ :tags: sql
+ :tickets: 2089
+
+ Added accessors to ResultProxy "returns_rows",
+ "is_insert" (also in 0.6.7)
+
+ .. change::
+ :tags: engine
+ :tickets: 2097
+
+ Fixed AssertionPool regression bug.
+
+ .. change::
+ :tags: engine
+ :tickets: 2060
+
+ Changed exception raised to ArgumentError when an
+ invalid dialect is specified.
+
+ .. change::
+ :tags: postgresql
+ :tickets: 2092
+
+ Added RESERVED_WORDS for postgresql dialect.
+ (also in 0.6.7)
+
+ .. change::
+ :tags: postgresql
+ :tickets: 2073
+
+ Fixed the BIT type to allow a "length" parameter, "varying"
+ parameter. Reflection also fixed.
+ (also in 0.6.7)
+
+ .. change::
+ :tags: mssql
+ :tickets: 2071
+
+ Rewrote the query used to get the definition of a view,
+ typically when using the Inspector interface, to
+ use sys.sql_modules instead of the information schema,
+ thereby allowing views definitions longer than 4000
+ characters to be fully returned.
+ (also in 0.6.7)
+
+ .. change::
+ :tags: firebird
+ :tickets: 2083
+
+ The "implicit_returning" flag on create_engine() is
+ honored if set to False. (also in 0.6.7)
+
+ .. change::
+ :tags: informix
+ :tickets: 2092
+
+ Added RESERVED_WORDS informix dialect.
+ (also in 0.6.7)
+
+ .. change::
+ :tags: ext
+ :tickets: 2090
+
+ The horizontal_shard ShardedSession class accepts the common
+ Session argument "query_cls" as a constructor argument,
+ to enable further subclassing of ShardedQuery. (also in 0.6.7)
+
+ .. change::
+ :tags: examples
+ :tickets:
+
+ Updated the association, association proxy examples
+ to use declarative, added a new example
+ dict_of_sets_with_default.py, a "pushing the envelope"
+ example of association proxy.
+
+ .. change::
+ :tags: examples
+ :tickets: 2090
+
+ The Beaker caching example allows a "query_cls" argument
+ to the query_callable() function.
+ (also in 0.6.7)
+
+.. changelog::
+ :version: 0.7.0b2
+ :released: Sat Feb 19 2011
+
+ .. change::
+ :tags: orm
+ :tickets: 2053
+
+ Fixed bug whereby Session.merge() would call the
+ load() event with one too few arguments.
+
+ .. change::
+ :tags: orm
+ :tickets: 2052
+
+ Added logic which prevents the generation of
+ events from a MapperExtension or SessionExtension
+ from generating do-nothing events for all the methods
+ not overridden.
+
+ .. change::
+ :tags: declarative
+ :tickets: 2058
+
+ Fixed regression whereby composite() with
+ Column objects placed inline would fail
+ to initialize. The Column objects can now
+ be inline with the composite() or external
+ and pulled in via name or object ref.
+
+ .. change::
+ :tags: declarative
+ :tickets: 2061
+
+ Fix error message referencing old @classproperty
+ name to reference @declared_attr
+ (also in 0.6.7)
+
+ .. change::
+ :tags: declarative
+ :tickets: 1468
+
+ the dictionary at the end of the __table_args__
+ tuple is now optional.
+
+ .. change::
+ :tags: sql
+ :tickets: 2059
+
+ Renamed the EngineEvents event class to
+ ConnectionEvents. As these classes are never
+ accessed directly by end-user code, this strictly
+ is a documentation change for end users. Also
+ simplified how events get linked to engines
+ and connections internally.
+
+ .. change::
+ :tags: sql
+ :tickets: 2055
+
+ The Sequence() construct, when passed a MetaData()
+ object via its 'metadata' argument, will be
+ included in CREATE/DROP statements within
+ metadata.create_all() and metadata.drop_all(),
+ including "checkfirst" logic.
+
+ .. change::
+ :tags: sql
+ :tickets: 2064
+
+ The Column.references() method now returns True
+ if it has a foreign key referencing the
+ given column exactly, not just it's parent
+ table.
+
+ .. change::
+ :tags: postgresql
+ :tickets: 2065
+
+ Fixed regression from 0.6 where SMALLINT and
+ BIGINT types would both generate SERIAL
+ on an integer PK column, instead of
+ SMALLINT and BIGSERIAL
+
+ .. change::
+ :tags: ext
+ :tickets: 2054
+
+ Association proxy now has correct behavior for
+ any(), has(), and contains() when proxying
+ a many-to-one scalar attribute to a one-to-many
+ collection (i.e. the reverse of the 'typical'
+ association proxy use case)
+
+ .. change::
+ :tags: examples
+ :tickets:
+
+ Beaker example now takes into account 'limit'
+ and 'offset', bind params within embedded
+ FROM clauses (like when you use union() or
+ from_self()) when generating a cache key.
+
+.. changelog::
+ :version: 0.7.0b1
+ :released: Sat Feb 12 2011
+
+ .. change::
+ :tags: examples
+ :tickets:
+
+ Detailed descriptions of each change below are
+ described at:
+ http://www.sqlalchemy.org/trac/wiki/07Migration
+
+ .. change::
+ :tags: general
+ :tickets: 1902
+
+ New event system, supercedes all extensions, listeners,
+ etc.
+
+ .. change::
+ :tags: general
+ :tickets: 1926
+
+ Logging enhancements
+
+ .. change::
+ :tags: general
+ :tickets: 1949
+
+ Setup no longer installs a Nose plugin
+
+ .. change::
+ :tags: general
+ :tickets:
+
+ The "sqlalchemy.exceptions" alias in sys.modules
+ has been removed. Base SQLA exceptions are
+ available via "from sqlalchemy import exc".
+ The "exceptions" alias for "exc" remains in
+ "sqlalchemy" for now, it's just not patched into
+ sys.modules.
+
+ .. change::
+ :tags: orm
+ :tickets: 1923
+
+ More succinct form of query.join(target, onclause)
+
+ .. change::
+ :tags: orm
+ :tickets: 1903
+
+ Hybrid Attributes, implements/supercedes synonym()
+
+ .. change::
+ :tags: orm
+ :tickets: 2008
+
+ Rewrite of composites
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Mutation Event Extension, supercedes "mutable=True"
+
+ .. change::
+ :tags: orm
+ :tickets: 1980
+
+ PickleType and ARRAY mutability turned off by default
+
+ .. change::
+ :tags: orm
+ :tickets: 1895
+
+ Simplified polymorphic_on assignment
+
+ .. change::
+ :tags: orm
+ :tickets: 1912
+
+ Flushing of Orphans that have no parent is allowed
+
+ .. change::
+ :tags: orm
+ :tickets: 2041
+
+ Adjusted flush accounting step to occur before
+ the commit in the case of autocommit=True. This allows
+ autocommit=True to work appropriately with
+ expire_on_commit=True, and also allows post-flush session
+ hooks to operate in the same transactional context
+ as when autocommit=False.
+
+ .. change::
+ :tags: orm
+ :tickets: 1973
+
+ Warnings generated when collection members, scalar referents
+ not part of the flush
+
+ .. change::
+ :tags: orm
+ :tickets: 1876
+
+ Non-`Table`-derived constructs can be mapped
+
+ .. change::
+ :tags: orm
+ :tickets: 1942
+
+ Tuple label names in Query Improved
+
+ .. change::
+ :tags: orm
+ :tickets: 1892
+
+ Mapped column attributes reference the most specific
+ column first
+
+ .. change::
+ :tags: orm
+ :tickets: 1896
+
+ Mapping to joins with two or more same-named columns
+ requires explicit declaration
+
+ .. change::
+ :tags: orm
+ :tickets: 1875
+
+ Mapper requires that polymorphic_on column be present
+ in the mapped selectable
+
+ .. change::
+ :tags: orm
+ :tickets: 1966
+
+ compile_mappers() renamed configure_mappers(), simplified
+ configuration internals
+
+ .. change::
+ :tags: orm
+ :tickets: 2018
+
+ the aliased() function, if passed a SQL FromClause element
+ (i.e. not a mapped class), will return element.alias()
+ instead of raising an error on AliasedClass.
+
+ .. change::
+ :tags: orm
+ :tickets: 2027
+
+ Session.merge() will check the version id of the incoming
+ state against that of the database, assuming the mapping
+ uses version ids and incoming state has a version_id
+ assigned, and raise StaleDataError if they don't
+ match.
+
+ .. change::
+ :tags: orm
+ :tickets: 1996
+
+ Session.connection(), Session.execute() accept 'bind',
+ to allow execute/connection operations to participate
+ in the open transaction of an engine explicitly.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ Query.join(), Query.outerjoin(), eagerload(),
+ eagerload_all(), others no longer allow lists
+ of attributes as arguments (i.e. option([x, y, z])
+ form, deprecated since 0.5)
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ ScopedSession.mapper is removed (deprecated since 0.5).
+
+ .. change::
+ :tags: orm
+ :tickets: 2031
+
+ Horizontal shard query places 'shard_id' in
+ context.attributes where it's accessible by the
+ "load()" event.
+
+ .. change::
+ :tags: orm
+ :tickets: 2032
+
+ A single contains_eager() call across
+ multiple entities will indicate all collections
+ along that path should load, instead of requiring
+ distinct contains_eager() calls for each endpoint
+ (which was never correctly documented).
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ The "name" field used in orm.aliased() now renders
+ in the resulting SQL statement.
+
+ .. change::
+ :tags: orm
+ :tickets: 1473
+
+ Session weak_instance_dict=False is deprecated.
+
+ .. change::
+ :tags: orm
+ :tickets: 2046
+
+ An exception is raised in the unusual case that an
+ append or similar event on a collection occurs after
+ the parent object has been dereferenced, which
+ prevents the parent from being marked as "dirty"
+ in the session. Was a warning in 0.6.6.
+
+ .. change::
+ :tags: orm
+ :tickets: 1069
+
+ Query.distinct() now accepts column expressions
+ as *args, interpreted by the Postgresql dialect
+ as DISTINCT ON (<expr>).
+
+ .. change::
+ :tags: orm
+ :tickets: 2049
+
+ Additional tuning to "many-to-one" relationship
+ loads during a flush(). A change in version 0.6.6
+ ([ticket:2002]) required that more "unnecessary" m2o
+ loads during a flush could occur. Extra loading modes have
+ been added so that the SQL emitted in this
+ specific use case is trimmed back, while still
+ retrieving the information the flush needs in order
+ to not miss anything.
+
+ .. change::
+ :tags: orm
+ :tickets:
+
+ the value of "passive" as passed to
+ attributes.get_history() should be one of the
+ constants defined in the attributes package. Sending
+ True or False is deprecated.
+
+ .. change::
+ :tags: orm
+ :tickets: 2030
+
+ Added a `name` argument to `Query.subquery()`, to allow
+ a fixed name to be assigned to the alias object. (also in 0.6.7)
+
+ .. change::
+ :tags: orm
+ :tickets: 2019
+
+ A warning is emitted when a joined-table inheriting mapper
+ has no primary keys on the locally mapped table
+ (but has pks on the superclass table).
+ (also in 0.6.7)
+
+ .. change::
+ :tags: orm
+ :tickets: 2038
+
+ Fixed bug where "middle" class in a polymorphic hierarchy
+ would have no 'polymorphic_on' column if it didn't also
+ specify a 'polymorphic_identity', leading to strange
+ errors upon refresh, wrong class loaded when querying
+ from that target. Also emits the correct WHERE criterion
+ when using single table inheritance.
+ (also in 0.6.7)
+
+ .. change::
+ :tags: orm
+ :tickets: 1995
+
+ Fixed bug where a column with a SQL or server side default
+ that was excluded from a mapping with include_properties
+ or exclude_properties would result in UnmappedColumnError. (also in 0.6.7)
+
+ .. change::
+ :tags: orm
+ :tickets: 2046
+
+ A warning is emitted in the unusual case that an
+ append or similar event on a collection occurs after
+ the parent object has been dereferenced, which
+ prevents the parent from being marked as "dirty"
+ in the session. This will be an exception in 0.7. (also in 0.6.7)
+
+ .. change::
+ :tags: declarative
+ :tickets: 2050
+
+ Added an explicit check for the case that the name
+ 'metadata' is used for a column attribute on a
+ declarative class. (also in 0.6.7)
+
+ .. change::
+ :tags: sql
+ :tickets: 1844
+
+ Added over() function, method to FunctionElement
+ classes, produces the _Over() construct which
+ in turn generates "window functions", i.e.
+ "<window function> OVER (PARTITION BY <partition by>,
+ ORDER BY <order by>)".
+
+ .. change::
+ :tags: sql
+ :tickets: 805
+
+ LIMIT/OFFSET clauses now use bind parameters
+
+ .. change::
+ :tags: sql
+ :tickets: 1069
+
+ select.distinct() now accepts column expressions
+ as *args, interpreted by the Postgresql dialect
+ as DISTINCT ON (<expr>). Note this was already
+ available via passing a list to the `distinct`
+ keyword argument to select().
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ select.prefix_with() accepts multiple expressions
+ (i.e. *expr), 'prefix' keyword argument to select()
+ accepts a list or tuple.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Passing a string to the `distinct` keyword argument
+ of `select()` for the purpose of emitting special
+ MySQL keywords (DISTINCTROW etc.) is deprecated -
+ use `prefix_with()` for this.
+
+ .. change::
+ :tags: sql
+ :tickets: 2006, 2005
+
+ TypeDecorator works with primary key columns
+
+ .. change::
+ :tags: sql
+ :tickets: 1897
+
+ DDL() constructs now escape percent signs
+
+ .. change::
+ :tags: sql
+ :tickets: 1917, 1893
+
+ Table.c / MetaData.tables refined a bit, don't allow direct
+ mutation
+
+ .. change::
+ :tags: sql
+ :tickets: 1950
+
+ Callables passed to `bindparam()` don't get evaluated
+
+ .. change::
+ :tags: sql
+ :tickets: 1870
+
+ types.type_map is now private, types._type_map
+
+ .. change::
+ :tags: sql
+ :tickets: 1982
+
+ Non-public Pool methods underscored
+
+ .. change::
+ :tags: sql
+ :tickets: 723
+
+ Added NULLS FIRST and NULLS LAST support. It's implemented
+ as an extension to the asc() and desc() operators, called
+ nullsfirst() and nullslast().
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ The Index() construct can be created inline with a Table
+ definition, using strings as column names, as an alternative
+ to the creation of the index outside of the Table.
+
+ .. change::
+ :tags: sql
+ :tickets: 2001
+
+ execution_options() on Connection accepts
+ "isolation_level" argument, sets transaction isolation
+ level for that connection only until returned to the
+ connection pool, for thsoe backends which support it
+ (SQLite, Postgresql)
+
+ .. change::
+ :tags: sql
+ :tickets: 2005
+
+ A TypeDecorator of Integer can be used with a primary key
+ column, and the "autoincrement" feature of various dialects
+ as well as the "sqlite_autoincrement" flag will honor
+ the underlying database type as being Integer-based.
+
+ .. change::
+ :tags: sql
+ :tickets: 2020, 2021
+
+ Established consistency when server_default is present
+ on an Integer PK column. SQLA doesn't pre-fetch these,
+ nor do they come back in cursor.lastrowid (DBAPI).
+ Ensured all backends consistently return None
+ in result.inserted_primary_key for these. Regarding
+ reflection for this case, reflection of an int PK col
+ with a server_default sets the "autoincrement" flag to False,
+ except in the case of a PG SERIAL col where we detected a
+ sequence default.
+
+ .. change::
+ :tags: sql
+ :tickets: 2006
+
+ Result-row processors are applied to pre-executed SQL
+ defaults, as well as cursor.lastrowid, when determining
+ the contents of result.inserted_primary_key.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ Bind parameters present in the "columns clause" of a select
+ are now auto-labeled like other "anonymous" clauses,
+ which among other things allows their "type" to be meaningful
+ when the row is fetched, as in result row processors.
+
+ .. change::
+ :tags: sql
+ :tickets:
+
+ TypeDecorator is present in the "sqlalchemy" import space.
+
+ .. change::
+ :tags: sql
+ :tickets: 2015
+
+ Non-DBAPI errors which occur in the scope of an `execute()`
+ call are now wrapped in sqlalchemy.exc.StatementError,
+ and the text of the SQL statement and repr() of params
+ is included. This makes it easier to identify statement
+ executions which fail before the DBAPI becomes
+ involved.
+
+ .. change::
+ :tags: sql
+ :tickets: 2048
+
+ The concept of associating a ".bind" directly with a
+ ClauseElement has been explicitly moved to Executable,
+ i.e. the mixin that describes ClauseElements which represent
+ engine-executable constructs. This change is an improvement
+ to internal organization and is unlikely to affect any
+ real-world usage.
+
+ .. change::
+ :tags: sql
+ :tickets: 2028
+
+ Column.copy(), as used in table.tometadata(), copies the
+ 'doc' attribute. (also in 0.6.7)
+
+ .. change::
+ :tags: sql
+ :tickets: 2023
+
+ Added some defs to the resultproxy.c extension so that
+ the extension compiles and runs on Python 2.4. (also in 0.6.7)
+
+ .. change::
+ :tags: sql
+ :tickets: 2042
+
+ The compiler extension now supports overriding the default
+ compilation of expression._BindParamClause including that
+ the auto-generated binds within the VALUES/SET clause
+ of an insert()/update() statement will also use the new
+ compilation rules. (also in 0.6.7)
+
+ .. change::
+ :tags: sql
+ :tickets: 1921
+
+ SQLite dialect now uses `NullPool` for file-based databases
+
+ .. change::
+ :tags: sql
+ :tickets: 2036
+
+ The path given as the location of a sqlite database is now
+ normalized via os.path.abspath(), so that directory changes
+ within the process don't affect the ultimate location
+ of a relative file path.
+
+ .. change::
+ :tags: postgresql
+ :tickets: 1083
+
+ When explicit sequence execution derives the name
+ of the auto-generated sequence of a SERIAL column,
+ which currently only occurs if implicit_returning=False,
+ now accommodates if the table + column name is greater
+ than 63 characters using the same logic Postgresql uses. (also in 0.6.7)
+
+ .. change::
+ :tags: postgresql
+ :tickets: 2044
+
+ Added an additional libpq message to the list of "disconnect"
+ exceptions, "could not receive data from server" (also in 0.6.7)
+
+ .. change::
+ :tags: mssql
+ :tickets: 1833
+
+ the String/Unicode types, and their counterparts VARCHAR/
+ NVARCHAR, emit "max" as the length when no length is
+ specified, so that the default length, normally '1'
+ as per SQL server documentation, is instead
+ 'unbounded'. This also occurs for the VARBINARY type..
+
+ This behavior makes these types more closely compatible
+ with Postgresql's VARCHAR type which is similarly unbounded
+ when no length is specified.
+
+ .. change::
+ :tags: mysql
+ :tickets: 1991
+
+ New DBAPI support for pymysql, a pure Python port
+ of MySQL-python.
+
+ .. change::
+ :tags: mysql
+ :tickets: 2047
+
+ oursql dialect accepts the same "ssl" arguments in
+ create_engine() as that of MySQLdb.
+ (also in 0.6.7)
+
+ .. change::
+ :tags: firebird
+ :tickets: 1885
+
+ Some adjustments so that Interbase is supported as well.
+ FB/Interbase version idents are parsed into a structure
+ such as (8, 1, 1, 'interbase') or (2, 1, 588, 'firebird')
+ so they can be distinguished.
+
+ .. change::
+ :tags: drizzle
+ :tickets: 2003
+
+ New dialect for Drizzle, a MySQL variant. Uses MySQL-python
+ for the DBAPI.
--- /dev/null
+
+==============
+0.8 Changelog
+==============
+
+
+.. changelog::
+ :version: 0.8.0b1
+ :released:
+
+ .. change::
+ :tags: general
+ :tickets:
+
+ SQLAlchemy 0.8 now targets Python 2.5 and
+ above. Python 2.4 is no longer supported.
+
+ .. change::
+ :tags: removed, general
+ :tickets: 2433
+
+ The "sqlalchemy.exceptions"
+ synonym for "sqlalchemy.exc" is removed
+ fully.
+
+ .. change::
+ :tags: removed, orm
+ :tickets: 2442
+
+ 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.
+
+ .. change::
+ :tags: orm, moved
+ :tickets:
+
+ 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
+ the core.
+
+ .. change::
+ :tags: orm, feature
+ :tickets: 1401
+
+ 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.
+
+ .. change::
+ :tags: orm, bug
+ :tickets: 2527
+
+ 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.
+
+ .. change::
+ :tags: orm, feature
+ :tickets: 2333
+
+ 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.
+
+ .. change::
+ :tags: orm, feature
+ :tickets: 1106, 2438
+
+ 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(),
+ contains_eager()
+
+ .. change::
+ :tags: orm, feature
+ :tickets: 2585
+
+ 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.
+
+ .. change::
+ :tags: orm, bug
+ :tickets: 2590
+
+ 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.
+
+ .. change::
+ :tags: orm, bug
+ :tickets: 1900
+
+ 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.
+
+ .. change::
+ :tags: orm, feature
+ :tickets: 2485
+
+ 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.
+
+ .. change::
+ :tags: orm, feature
+ :tickets: 2208
+
+ 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.
+
+ .. change::
+ :tags: orm, feature
+ :tickets: 2452
+
+ 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.
+
+ .. change::
+ :tags: orm, feature
+ :tickets: 2372
+
+ Added utility feature
+ Session.enable_relationship_loading(),
+ supersedes relationship.load_on_pending.
+ Both features should be avoided, however.
+
+ .. change::
+ :tags: orm, feature
+ :tickets:
+
+ Added support for .info dictionary argument to
+ column_property(), relationship(), composite().
+ All MapperProperty classes have an auto-creating .info
+ dict available overall.
+
+ .. change::
+ :tags: orm, feature
+ :tickets: 2229
+
+ Adding/removing None from a mapped collection
+ now generates attribute events. Previously, a None
+ append would be ignored in some cases. Related
+ to.
+
+ .. change::
+ :tags: orm, feature
+ :tickets: 2229
+
+ The presence of None in a mapped collection
+ now raises an error during flush. Previously,
+ None values in collections would be silently ignored.
+
+ .. change::
+ :tags: orm, feature
+ :tickets:
+
+ 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
+ in Core yet.
+
+ .. change::
+ :tags: orm, feature
+ :tickets:
+
+ 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
+ it deactivates.
+
+ .. change::
+ :tags: orm, feature
+ :tickets: 2592
+
+ 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.
+
+ .. change::
+ :tags: orm, bug
+ :tickets: 2481
+
+ 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".
+
+ .. change::
+ :tags: orm, bug
+ :tickets: 2320
+
+ 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.
+
+ .. change::
+ :tags: orm, bug
+ :tickets: 2405
+
+ 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.
+
+ .. change::
+ :tags: orm, bug
+ :tickets: 2350
+
+ 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
+ query. Previously,
+ 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.
+
+ .. change::
+ :tags: orm, feature
+ :tickets: 2179
+
+ 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.
+
+ .. change::
+ :tags: orm, feature
+ :tickets: 2464
+
+ 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.
+
+ .. change::
+ :tags: orm, feature
+ :tickets:
+
+ 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
+ flush events
+ 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
+ can't be guaranteed.
+
+ .. change::
+ :tags: orm, bug
+ :tickets: 2582, 2566
+
+ Continuing 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.
+
+ .. change::
+ :tags: orm, feature
+ :tickets: 2245
+
+ 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.
+
+ .. change::
+ :tags: orm, feature
+ :tickets: 2245
+
+ 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.
+
+ .. change::
+ :tags: orm, feature
+ :tickets: 2526
+
+ 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.
+
+ .. change::
+ :tags: orm, feature
+ :tickets: 2472
+
+ 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.
+
+ .. change::
+ :tags: orm, feature
+ :tickets: 2472
+
+ declared_attr can now be used
+ on non-mixin classes, even though this is generally
+ only useful for single-inheritance subclass
+ column conflict resolution.
+
+ .. change::
+ :tags: orm, feature
+ :tickets: 2517
+
+ 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.
+
+ .. change::
+ :tags: orm, bug
+ :tickets: 2565
+
+ 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.
+
+ .. change::
+ :tags: orm, feature
+ :tickets: 2526
+
+ *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
+ attributes in place.
+ 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.
+
+ .. change::
+ :tags: orm, feature
+ :tickets: 2338
+
+ 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.
+
+ .. change::
+ :tags: orm, feature
+ :tickets: 2535
+
+ Can now provide class-bound attributes
+ that override columns which are of any
+ non-ORM type, not just descriptors.
+
+ .. change::
+ :tags: orm, feature
+ :tickets: 1729
+
+ Added with_labels and
+ reduce_columns keyword arguments to
+ Query.subquery(), to provide two alternate
+ strategies for producing queries with uniquely-
+ named columns. .
+
+ .. change::
+ :tags: orm, feature
+ :tickets: 2476
+
+ 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.
+
+ .. change::
+ :tags: orm, bug
+ :tickets: 2549
+
+ 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.
+
+ .. change::
+ :tags: orm, bug
+ :tickets:
+
+ An error is emitted when uselist=False
+ is combined with a "dynamic" loader.
+ This is a warning in 0.7.9.
+
+ .. change::
+ :tags: removed, orm
+ :tickets:
+
+ 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()
+ (use load=True)
+
+ * sqlalchemy.orm.shard module
+ (use sqlalchemy.ext.horizontal_shard)
+
+ .. change::
+ :tags: engine, feature
+ :tickets: 2511
+
+ Connection event listeners can
+ now be associated with individual
+ Connection objects, not just Engine
+ objects.
+
+ .. change::
+ :tags: engine, feature
+ :tickets: 2459
+
+ 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.
+
+ .. change::
+ :tags: engine, feature
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: engine, bug
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: engine, bug
+ :tickets: 2522
+
+ 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.
+
+ .. change::
+ :tags: engine, feature
+ :tickets: 2462
+
+ Added a new system
+ for registration of new dialects in-process
+ without using an entrypoint. See the
+ docs for "Registering New Dialects".
+
+ .. change::
+ :tags: engine, feature
+ :tickets: 2556
+
+ 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.
+
+ .. change::
+ :tags: engine, feature
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: engine, bug
+ :tickets: 2397
+
+ 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.
+
+ .. change::
+ :tags: engine, feature
+ :tickets: 2422
+
+ Inspector.get_primary_keys() is
+ deprecated; use Inspector.get_pk_constraint().
+ Courtesy Diana Clarke.
+
+ .. change::
+ :tags: engine, bug
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: engine, bug
+ :tickets: 2498
+
+ 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.
+
+ .. change::
+ :tags: engine, feature
+ :tickets:
+
+ New C extension module "utils" has
+ been added for additional function speedups
+ as we have time to implement.
+
+ .. change::
+ :tags: engine
+ :tickets:
+
+ ResultProxy.last_inserted_ids is removed,
+ replaced by inserted_primary_key.
+
+ .. change::
+ :tags: feature, sql
+ :tickets: 2547
+
+ 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.
+
+ .. change::
+ :tags: feature, sql
+ :tickets: 1534, 2547
+
+ To complement, 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.
+
+ .. change::
+ :tags: feature, sql
+ :tickets:
+
+ 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
+ optional operators.
+
+ 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.
+
+ .. change::
+ :tags: feature, sql
+ :tickets: 2537
+
+ 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.
+
+ .. change::
+ :tags: feature, sql
+ :tickets: 2276
+
+ 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::
+ :tags: change, sql
+ :tickets:
+
+ The Text() type renders the length
+ given to it, if a length was specified.
+
+ .. change::
+ :tags: feature, sql
+ :tickets:
+
+ Custom unary operators can now be
+ used by combining operators.custom_op() with
+ UnaryExpression().
+
+ .. change::
+ :tags: bug, sql
+ :tickets: 2564
+
+ 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".
+
+ .. change::
+ :tags: feature, sql
+ :tickets:
+
+ 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
+ in func.*.
+
+ .. change::
+ :tags: feature, sql
+ :tickets: 2562
+
+ 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.
+
+ .. change::
+ :tags: changed, sql
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: feature, sql
+ :tickets: 2208
+
+ The Inspector object can now be
+ acquired using the new inspect() service,
+ part of
+
+ .. change::
+ :tags: feature, sql
+ :tickets: 2418
+
+ 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.
+
+ .. change::
+ :tags: feature, sql
+ :tickets: 2423
+
+ 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().
+
+ .. change::
+ :tags: bug, sql
+ :tickets: 2591
+
+ 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.
+
+ .. change::
+ :tags: feature, sql
+ :tickets: 2415
+
+ 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.
+
+ .. change::
+ :tags: feature, sql
+ :tickets: 2502
+
+ Added "MATCH" clause to ForeignKey,
+ ForeignKeyConstraint, courtesy Ryan Kelly.
+
+ .. change::
+ :tags: feature, sql
+ :tickets: 2507
+
+ 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.
+
+ .. change::
+ :tags: feature, sql
+ :tickets:
+
+ select() features a correlate_except()
+ method, auto correlates all selectables except those
+ passed.
+
+ .. change::
+ :tags: feature, sql
+ :tickets: 2431
+
+ 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.
+
+ .. change::
+ :tags: feature, sql
+ :tickets: 1729
+
+ 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
+ removed.
+
+ .. change::
+ :tags: feature, sql
+ :tickets: 2470
+
+ 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
+
+ .. change::
+ :tags: feature, sql
+ :tickets: 2463
+
+ 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.
+
+ .. change::
+ :tags: feature, sql
+ :tickets:
+
+ "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.
+
+ .. change::
+ :tags: bug, sql
+ :tickets: 2520
+
+ Fixes to the interpretation of the
+ Column "default" parameter as a callable
+ to not pass ExecutionContext into a keyword
+ argument parameter.
+
+ .. change::
+ :tags: bug, sql
+ :tickets: 2410
+
+ 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.
+
+ .. change::
+ :tags: bug, sql
+ :tickets: 2594
+
+ 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.
+
+ .. change::
+ :tags: bug, sql
+ :tickets: 2168
+
+ column.label(None) now produces an
+ anonymous label, instead of returning the
+ column object itself, consistent with the behavior
+ of label(column, None).
+
+ .. change::
+ :tags: feature, sql
+ :tickets: 2455
+
+ An explicit error is raised when
+ a ForeignKeyConstraint() that was
+ constructed to refer to multiple remote tables
+ is first used.
+
+ .. change::
+ :tags: access, feature
+ :tickets:
+
+ 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
+ functionality now.
+ https://bitbucket.org/zzzeek/sqlalchemy-access
+
+ .. change::
+ :tags: maxdb, moved
+ :tickets:
+
+ The MaxDB dialect, which hasn't been
+ functional for several years, is
+ moved out to a pending bitbucket project,
+ https://bitbucket.org/zzzeek/sqlalchemy-maxdb.
+
+ .. change::
+ :tags: sqlite, feature
+ :tickets: 2363
+
+ 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
+ this.
+
+ .. change::
+ :tags: mssql, feature
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: mssql, bug
+ :tickets: 2277
+
+ 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.
+
+ .. change::
+ :tags: mssql, feature
+ :tickets:
+
+ updated support for the mxodbc
+ driver; mxodbc 3.2.1 is recommended for full
+ compatibility.
+
+ .. change::
+ :tags: postgresql, feature
+ :tickets: 2441
+
+ 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.
+
+ .. change::
+ :tags: postgresql, feature
+ :tickets:
+
+ 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.
+
+ .. change::
+ :tags: postgresql, feature
+ :tickets:
+
+ Added new "array literal" construct
+ postgresql.array(). Basically a "tuple" that
+ renders as ARRAY[1,2,3].
+
+ .. change::
+ :tags: postgresql, feature
+ :tickets: 2506
+
+ 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
+
+ .. change::
+ :tags: postgresql, feature
+ :tickets:
+
+ 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
+ three reasons:
+
+ 1. this is not an "official" API. Ideally
+ an "official" API would allow custom type-handling
+ callables at the dialect or global level
+ in a generic way.
+ 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
+ default dialect level.
+ 3. The reflection code here is only tested against
+ simple types and probably has issues with more
+ compositional types.
+
+ patch courtesy Éric Lemoine.
+
+ .. change::
+ :tags: firebird, feature
+ :tickets: 2470
+
+ The "startswith()" operator renders
+ as "STARTING WITH", "~startswith()" renders
+ as "NOT STARTING WITH", using FB's more efficient
+ operator.
+
+ .. change::
+ :tags: firebird, bug
+ :tickets: 2505
+
+ CompileError is raised when VARCHAR with
+ no length is attempted to be emitted, same
+ way as MySQL.
+
+ .. change::
+ :tags: firebird, bug
+ :tickets:
+
+ Firebird now uses strict "ansi bind rules"
+ so that bound parameters don't render in the
+ columns clause of a statement - they render
+ literally instead.
+
+ .. change::
+ :tags: firebird, bug
+ :tickets:
+
+ Support for passing datetime as date when
+ using the DateTime type with Firebird; other
+ dialects support this.
+
+ .. change::
+ :tags: firebird, feature
+ :tickets: 2504
+
+ An experimental dialect for the fdb
+ driver is added, but is untested as I cannot
+ get the fdb package to build.
+
+ .. change::
+ :tags: bug, mysql
+ :tickets: 2404
+
+ Dialect no longer emits expensive server
+ collations query, as well as server casing,
+ on first connect. These functions are still
+ available as semi-private.
+
+ .. change::
+ :tags: feature, mysql
+ :tickets: 2534
+
+ 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.
+
+ .. change::
+ :tags: oracle, bug
+ :tickets: 2437
+
+ 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.
+
+ .. change::
+ :tags: oracle, feature
+ :tickets: 2561
+
+ 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.
+
+ .. change::
+ :tags: oracle, bug
+ :tickets:
+
+ 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
+ of the table.
+
+ .. change::
+ :tags: removed, extensions
+ :tickets: 2262
+
+ The SQLSoup extension is removed from
+ SQLAlchemy, and is now an external project.
+ See http://pypi.python.org/pypi/sqlsoup .
--- /dev/null
+.. _changelog_toplevel:
+
+Changes and Migration
+=====================
+
+Migration Guides
+----------------
+
+SQLAlchemy migration guides are currently available on the wiki.
+
+* `Version 0.8 <http://www.sqlalchemy.org/trac/wiki/08Migration>`_
+
+* `Version 0.7 <http://www.sqlalchemy.org/trac/wiki/07Migration>`_
+
+* `Version 0.6 <http://www.sqlalchemy.org/trac/wiki/06Migration>`_
+
+* `Version 0.5 <http://www.sqlalchemy.org/trac/wiki/05Migration>`_
+
+Change logs
+-----------
+
+SQLAlchemy changelogs are now available within the main documentation.
+
+.. toctree::
+ :maxdepth: 2
+
+ changelog_08
+ changelog_07
+ changelog_06
+ changelog_05
+ changelog_04
+ changelog_03
+ changelog_02
+ changelog_01
+
orm/index
core/index
dialects/index
+ changelog/index
Indices and tables
------------------
:ref:`Overview <overview>` |
:ref:`Installation Guide <installation>` |
-:ref:`Migration from 0.7 <migration>`
+:ref:`Migration from 0.7 <migration>` |
+:ref:`Changelog catalog <changelog/index>`
SQLAlchemy ORM
==============