0.7.9
=====
- sql
- - [bug] Fixed CTE bug whereby positional
+ - [bug] Fixed CTE bug whereby positional
bound parameters present in the CTEs themselves
- would corrupt the overall ordering of
+ would corrupt the overall ordering of
bound parameters. This primarily
- affected SQL Server as the platform with
- positional binds + CTE support.
+ affected SQL Server as the platform with
+ positional binds + CTE support.
[ticket:2521]
- [bug] quoting is applied to the column names
- inside the WITH RECURSIVE clause of a
- common table expression according to the
+ 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
+ - [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]
- 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
+ particular type of event until
+ instance-level listeners are established
for that event. [ticket:2516]
0.7.8
=====
- orm
- - [bug] Fixed bug whereby subqueryload() from
+ - [bug] Fixed bug whereby subqueryload() from
a polymorphic mapping to a target would incur
- a new invocation of the query for each
+ 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
+ - [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 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
+ - [feature] The 'objects' argument to
flush() is no longer deprecated, as some
- valid use cases have been identified.
+ valid use cases have been identified.
- - [bug] Fixed identity_key() function which
- was not accepting a scalar argument
+ - [bug] Fixed identity_key() function which
+ was not accepting a scalar argument
for the identity. [ticket:2508].
- [bug] Fixed bug whereby populate_existing
[ticket:2499]
- [bug] Repaired common table expression
- rendering to function correctly when the
+ rendering to function correctly when the
SELECT statement contains UNION or other
- compound expressions, courtesy btbuilder.
+ compound expressions, courtesy btbuilder.
[ticket:2490]
- [bug] Fixed bug whereby append_column()
wouldn't function correctly on a cloned
- select() construct, courtesy
+ select() construct, courtesy
Gunnlaugur Þór Briem. [ticket:2482]
- engine
is pyodbc. [ticket:2489]
- [bug] Fixed bug affecting Py3K whereby
- string positional parameters passed to
+ string positional parameters passed to
engine/connection execute() would fail to be
interpreted correctly, due to __iter__
- being present on Py3K string.
+ being present on Py3K string.
[ticket:2503].
- postgresql
directives in statements. Courtesy
Diana Clarke [ticket:2443]
- - [bug] Fixed bug in 0.7.6 introduced by
+ - [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
"is_remove" when this flag is used.
- [bug] Fixed bug whereby polymorphic_on
- column that's not otherwise mapped on the
+ 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
+ and joins, particularly when using
column_property(). [ticket:2453]
- [bug] Fixed bug which would prevent
- 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
+ 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
+ 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
+ Connection is closed explicitly before
propagating the exception onward normally.
- [bug] Add BINARY, VARBINARY to types.__all__,
- [feature] Added interim create_engine flag
supports_unicode_binds to PyODBC dialect,
to force whether or not the dialect
- passes Python unicode literals to PyODBC
+ 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
+ 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 FROM, when FROM is present
in the first place. Courtesy sayap.
[ticket:2468]
for_update="read_nowait"/
with_lockmode("read_nowait").
These emit "FOR SHARE" and "FOR SHARE NOWAIT",
- respectively. Courtesy Diana Clarke
+ respectively. Courtesy Diana Clarke
[ticket:2445]
- [bug] removed unnecessary table clause
- mysql
- - [bug] Fixed bug whereby column name inside
+ - [bug] Fixed bug whereby column name inside
of "KEY" clause for autoincrement composite
- column with InnoDB would double quote a
+ column with InnoDB would double quote a
name that's a reserved word. Courtesy Jeff
Dairiki. [ticket:2460]
- orm
- [bug] Fixed event registration bug
which would primarily show up as
- events not being registered with
+ events not being registered with
sessionmaker() instances created
after the event was associated
with the Session class. [ticket:2424]
[ticket:2403]
- [bug] Fixed bug whereby objects using
- attribute_mapped_collection or
+ attribute_mapped_collection or
column_mapped_collection could not be
pickled. [ticket:2409]
would not get the appropriate collection
instrumentation if it were only used
in a custom subclass that used
- @collection.internally_instrumented.
+ @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.
+ derived function in the columns clause.
[ticket:2419]
- [bug] Fixed the repr() for CascadeOptions to
[ticket:2417]
- [feature] Added the ability to query for
- Table-bound column names when using
- query(sometable).filter_by(colname=value).
+ Table-bound column names when using
+ query(sometable).filter_by(colname=value).
[ticket:2400]
- - [bug] Improved the "declarative reflection"
+ - [bug] Improved the "declarative reflection"
example to support single-table inheritance,
multiple calls to prepare(), tables that
are present in alternate schemas,
as reflected.
- [bug] Scaled back the test applied within
- flush() to check for UPDATE against partially
- NULL PK within one table to only actually
+ 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]
were called. [ticket:2427]
- [bug] Fixed issue whereby attribute-based
- column access on a row would raise
+ column access on a row would raise
AttributeError with non-C version,
NoSuchColumnError with C version. Now
raises AttributeError in both cases.
[ticket:1859]
- [bug] Added support for using the .key
- of a Column as a string identifier in a
+ 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
+ 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
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
+ 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
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
+ 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
+ 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
+ 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
[ticket:2432]
- mssql
- - [feature] Added support for MSSQL INSERT,
+ - [feature] Added support for MSSQL INSERT,
UPDATE, and DELETE table hints, using
new with_hint() method on UpdateBase.
[ticket:2430]
- [feature] Added support for MySQL index and
primary key constraint types
(i.e. USING) via new mysql_using parameter
- to Index and PrimaryKeyConstraint,
+ to Index and PrimaryKeyConstraint,
courtesy Diana Clarke. [ticket:2386]
- [feature] Added support for the "isolation_level"
- [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
+ by converting all numeric values to
Decimal. [ticket:2399]
- - [bug] Added missing compilation support for
+ - [bug] Added missing compilation support for
LONG [ticket:2401]
- [bug] Added 'LEVEL' to the list of reserved
- 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
+ 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
+ is present, a warning is emitted and
restore_snapshot() is called a second time,
discarding those changes. [ticket:2389]
declarative_base(). Allows two or more declarative
bases to share the same registry of class names.
- - [feature] query.filter() accepts multiple
+ - [feature] query.filter() accepts multiple
criteria which will join via AND, i.e.
query.filter(x==y, z>q, ...)
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
+ 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
+ forced an entirely unnecessary compile of the
mapper, making events very hard to set up
- at module import time (nobody noticed this ??)
+ at module import time (nobody noticed this ??)
[ticket:2367]
- - [bug] Fixed bug whereby hybrid_property didn't
+ - [bug] Fixed bug whereby hybrid_property didn't
work as a kw arg in any(), has().
- - Fixed regression from 0.6 whereby if
+ - 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
+ 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
+ - [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
+ - [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
+ 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
+ load_on_pending flag were used with
relationship(). Thanks to Kent Bower
for tests. [ticket:2374]
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
+ 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,
+ 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]
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
+ 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]
[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
+ - [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
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
+ - [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
+ 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
+ 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
+ - [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
+ to fall back to an older version of
+ SQLite that doesn't have the
"sqlite_temp_master" table.
- mysql
- [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
+ 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
- [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
+ 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
+ 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
+ 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
+ a bit to use a declarative mixin as well
as an event listener, instead of a metaclass +
SessionExtension. [ticket:2313]
0.7.4 (December 9, 2011)
=====
- orm
- - [bug] Fixed backref behavior when "popping" the
- value off of a many-to-one in response to
+ - [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"
+ 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
+ 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
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
+ 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
+ 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
+ as before; it's advised to expire X also in that
case. [ticket:2264]
- [bug] fixed inappropriate evaluation of user-mapped
- [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
+ 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]
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
+ 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.
a distinct entity when producing certain
kinds of joined-inh joins. [ticket:2316]
- - [bug] Fixed the error formatting raised when
+ - [bug] Fixed the error formatting raised when
a tuple is inadvertently passed to session.query()
[ticket:2297]. Also in 0.6.9.
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
+ fewer WHERE criterion when dealing with
single table inheritance joins.
[ticket:2328]
- - [bug] __table_args__ can now be passed as
+ - [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
+ 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]
- string names of any column_property()
or attribute name of a mapped Column
- The docs include an example using
+ 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]
subclass as is the usual behavior.
- [feature] IdentitySet supports the - operator
- as the same as difference(), handy when dealing
+ as the same as difference(), handy when dealing
with Session.dirty etc. [ticket:2301]
- [feature] Added new value for Column autoincrement
- [bug] Fixed bug in get_history() when referring
to a composite attribute that has no value;
- added coverage for get_history() regarding
+ added coverage for get_history() regarding
composites which is otherwise just a userland
function.
- sql
- - [bug] related to [ticket:2316], made some
+ - [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
+ 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
+ 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
+ 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
- [feature] The update() construct can now accommodate
multiple tables in the WHERE clause, which will
- render an "UPDATE..FROM" construct, recognized by
+ 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
- engine
- [bug] Fixed bug whereby transaction.rollback()
- would throw an error on an invalidated
- connection if the transaction were a
+ 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
- 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
+ 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.
- [feature] The "extend_existing" flag on Table
now allows for the reflection process to take
- effect for a Table object that's already been
+ 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
+ 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
like the CHAR/UUID type.
- [bug] Fixed bug whereby "order_by='foreign_key'"
- option to Inspector.get_table_names
+ 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>".
+ 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
+ - [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
+ - [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
+ "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
+ - [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
+ of a table create/drop event; only the
create()/drop)() methods called directly
will do this. Helps with Alembic "offline"
scripts.
however. [ticket:822]
- [bug] repaired the with_hint() feature which
- wasn't implemented correctly on MSSQL -
+ wasn't implemented correctly on MSSQL -
usually used for the "WITH (NOLOCK)" hint
- (which you shouldn't be using anyway !
+ (which you shouldn't be using anyway !
use snapshot isolation instead :) )
[ticket:2336]
within those indexes. [ticket:2269]
- mysql
- - [bug] Unicode adjustments allow latest pymysql
+ - [bug] Unicode adjustments allow latest pymysql
(post 0.4) to pass 100% on Python 2.
- ext
- examples
- [bug] Fixed bug in history_meta.py example where
- the "unique" flag was not removed from a
- single-table-inheritance subclass which
+ the "unique" flag was not removed from a
+ single-table-inheritance subclass which
generates columns to put up onto the base.
0.7.3
- orm
- Improved query.join() such that the "left" side
- can more flexibly be a non-ORM selectable,
+ 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
+ foreign keys, the error message includes
this detail. Thanks to brianrhude
on IRC for the test case. [ticket:2298]
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
method will be preserved, including required kw rules.
[ticket:2237]
- - Fixed bug in unit of work whereby detection of
+ - 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
+ issues down the road. Note this bug is in 0.6
also; not backported at the moment.
[ticket:2282]
to query.with_parent().
- Fixed bug whereby mapper.order_by attribute would
- be ignored in the "inner" query within a
+ 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
+ - 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
+ - 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
+ twice. Thanks *much* to Dave Vitek
for the excellent fix here. [ticket:2247]
- Query will convert an OFFSET of zero when
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
+ that is not a "type" (i.e. a class that could
potentially be mapped) now raises an informative
ArgumentError, rather than UnmappedClassError.
[ticket:2196]
to the mapper after it has already been configured.
[ticket:2239]
- - Declarative will warn when a subclass' base uses
+ - 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
+ eliminate the possibility of recycled id() values
+ causing an incorrect result, no need to check that
object actually in the session. [ticket:2280]
-sql
i.e. and_(x, or_()) will produce 'X' and not 'X AND
()'. [ticket:2257].
- - Fixed bug regarding calculation of "from" list
+ - 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
+ 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
+ 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]
[ticket:2270]. Also in 0.6.9.
- schema
- - Modified Column.copy() to use _constructor(),
- which defaults to self.__class__, in order to
+ - 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]
- 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
+ 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
+ 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
+ - 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
+ - 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
+ or entry point-resolved dialect, using the
standard '+' notation - it's converted to
a '.' before being resolved as an entry
point. [ticket:2286]
type implemented. [ticket:2299]
- types
- - Extra keyword arguments to the base Float
+ - 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
+ the database regardless of whether C
extensions are in use or not.
- postgresql
calls the psycopg2 set_client_encoding() method
with the value upon connect. [ticket:1839]
- - Fixed bug related to [ticket:2141] whereby the
+ - 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.
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;
+ - 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
+ 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
+ - 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.
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
+ - 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
+ 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
+ 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
+ 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
+ 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]
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
+ 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),
+ 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
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
+ soon be superseded by a third party
project. [ticket:2262]
- Added local_attr, remote_attr, attr accessors
- 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
+ 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
+ to apply the CAST such that it works on
PG, other databases. [ticket:2266]
Also in 0.6.9.
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
+ 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
+ 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
+ from a joined-inh structure to itself on
relationship() with join condition on the child
- table would convert the lead entity into the
+ 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
+ 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
+ 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
+ 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
- Fixed regression from 0.6 where a get history
operation on some relationship() based attributes
- would fail when a lazyload would emit; this could
+ 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
+ if the persistent object primary key
is not a single integer. [ticket:2228]
Also in 0.6.9
result set. [ticket:2215]
Also in 0.6.9.
- - Added public attribute ".validators" to
- Mapper, an immutable dictionary view of
+ - 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
- 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
+ bindparams, rather than incorrectly repeating
the same bindparam. [ticket:2207].
Also in 0.6.9.
- - Added the same "columns-only" check to
+ - Added the same "columns-only" check to
mapper.polymorphic_on as used when
receiving user arguments to
relationship.order_by, foreign_keys,
- Fixed bug whereby comparison of column
expression to a Query() would not call
- as_scalar() on the underlying SELECT
+ 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]
due to an unnecessary lookup of the name
in the _decl_class_registry. [ticket:2194]
- - Repaired the "no statement condition"
+ - 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
+ - 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
+ when the label has been "grouped" and
loses itself. Affects [ticket:2188].
- schema
- - New feature: with_variant() method on
+ - 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
+ - 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
+ 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
+ - Fixed bug where "autoincrement" detection on
Table would fail if the type had no "affinity"
- value, in particular this would occur when using
+ value, in particular this would occur when using
the UUID example on the site that uses TypeEngine
as the "impl".
- 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
+ wrapped in StatementException when they
+ occur in the context of a statement
execution.
- StatementException wrapping will display the
- Failures on connect which raise dbapi.Error
will forward the error to dialect.is_disconnect()
- and set the "connection_invalidated" flag if
+ 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]
the default. [ticket:2189]
- postgresql
- - Added new "postgresql_ops" argument to
+ - 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
+ - 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.
+ 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
+ - 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
+ can be caught during a connection
event. [ticket:2201]
- repaired the oracle.RAW type which did not
would not get instrumented.
- Fixed bug in the mutable extension whereby
- if None or a non-corresponding type were set,
+ 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.
inheritance situation.
- Fixed the attribute shard example to check
- for bind param callable correctly in 0.7
+ 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
+ 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
+ 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
+ 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
+ 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].
- Fixed bug where transaction-level "deleted"
collection wouldn't be cleared of expunged
states, raising an error if they later
- became transient [ticket:2182].
+ became transient [ticket:2182].
Also in 0.6.8.
- sql
- 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([])
+ 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
+ - Deprecate schema/SQL-oriented methods on
Connection/Engine that were never well known
- and are redundant: reflecttable(), create(),
+ and are redundant: reflecttable(), create(),
drop(), text(), engine.func
- - Adjusted the __contains__() method of
+ - 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
+ 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.
- 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
+ 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,
+ - 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
+ 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.
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
+ been determined that this step wasn't really
helping the situation much; MySQL does not return
- FK names with proper casing on non-windows
+ 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
+ has been considered but its difficult to
determine under what conditions such a warning
- can be raised, so punted on that for now -
+ 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
+ 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
+ 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 up some of the error messages tailored
in [ticket:2069]
- - query.count() emits "count(*)" instead of
+ - 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"
+ 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.
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
+ of that with no cols in the sub-sub class
in the join condition. [ticket:2149]
Also in 0.6.8.
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
+ 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
are determined.
- It is an error to call query.get() when the
- given entity is not a single, full class
+ 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
+ circumstances could occur with the identity
map, part of [ticket:2148]
- - added Query.with_session() method, switches
+ - added Query.with_session() method, switches
Query to use a different session.
- horizontal shard query should use execution
- 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
+ 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
+ mapper 'X' does not map this column" to
reference the correct mapper. [ticket:2163].
Also in 0.6.8.
- 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
+ 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
+ alias would fail if logging were used, due to
unescaped % sign in the alias name. [ticket:2171]
Also in 0.6.8.
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
+ 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
+ connections are really closed when very
unusual DBAPI errors occur.
- - metadata.reflect() and reflection.Inspector()
+ - metadata.reflect() and reflection.Inspector()
had some reliance on GC to close connections
which were internally procured, fixed this.
patterns. [ticket:2147] also in 0.6.8
- postgresql
- - Fixed the psycopg2_version parsing in the
+ - Fixed the psycopg2_version parsing in the
psycopg2 dialect.
- Fixed bug affecting PG 9 whereby index reflection
- examples
- removed the ancient "polymorphic association"
examples and replaced with an updated set of
- examples that use declarative mixins,
+ examples that use declarative mixins,
"generic_associations". Each presents an alternative
table layout.
=======
- general
- Changes to the format of CHANGES, this file.
- The format changes have been applied to
+ The format changes have been applied to
the 0.7 releases.
- The "-declarative" changes will now be listed
CHANGES_PRE_05.
- The changelog for 0.6.7 and subsequent within
- the 0.6 series is now listed only in the
+ 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
+ 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
+ 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
+ in all cases, and before update/delete is
emitted, guarding against unflushed data present
- as well as expired objects failing during
+ as well as expired objects failing during
the evaluation. [ticket:2122]
- Reworded the exception raised when a flush
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
+ - 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
+ 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).
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
+ 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
- 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
+ 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
+ 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
Integer(11) still succeeds.
- Fixed regression whereby MetaData() coming
- back from unpickling did not keep track of
+ 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]
- 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
+ typically converted straight to string, which was
no longer accepted in 0.7. [ticket:2117]
- engine
- schema
- The 'useexisting' flag on Table has been superceded
- by a new pair of flags 'keep_existing' and
+ 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.
- 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
+ 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
+ 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
+ the assertion raised upon a second concurrent
+ checkout; courtesy Gunnlaugur Briem
[ticket:2103]
- The "pool.manage" feature doesn't use pickle
- Documented SQLite DATE/TIME/DATETIME types.
[ticket:2029] (also in 0.6.7)
- - Fixed mutable extension docs to show the
+ - Fixed mutable extension docs to show the
correct type-association methods.
[ticket:2118]
scalar()
That is, "select count(1) from (<full query>)".
- This produces a subquery in all cases, but
+ 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
+ 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
+ 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
+ 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()
+ 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
+ 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
+ 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,
+ 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
+ - 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
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
+ 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
+ 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
- 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,
+ 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",
+ - Added accessors to ResultProxy "returns_rows",
"is_insert" [ticket:2089] (also in 0.6.7)
- engine
- examples
- Updated the association, association proxy examples
- to use declarative, added a new example
- dict_of_sets_with_default.py, a "pushing the envelope"
+ 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]
+ to the query_callable() function. [ticket:2090]
(also in 0.6.7)
0.7.0b2
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
+ - 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
+ - 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.
+ and pulled in via name or object ref.
[ticket:2058]
- Fix error message referencing old @classproperty
tuple is now optional. [ticket:1468]
- sql
- - Renamed the EngineEvents event class to
+ - 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
+ - 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(),
+ metadata.create_all() and metadata.drop_all(),
including "checkfirst" logic. [ticket:2055]
- The Column.references() method now returns True
- postgresql
- Fixed regression from 0.6 where SMALLINT and
BIGINT types would both generate SERIAL
- on an integer PK column, instead of
+ on an integer PK column, instead of
SMALLINT and BIGSERIAL [ticket:2065]
- ext
- examples
- Beaker example now takes into account 'limit'
and 'offset', bind params within embedded
- FROM clauses (like when you use union() or
+ 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
+- Detailed descriptions of each change below are
described at:
http://www.sqlalchemy.org/trac/wiki/07Migration
[ticket:1949]
- The "sqlalchemy.exceptions" alias in sys.modules
- has been removed. Base SQLA exceptions are
+ 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
+ The "exceptions" alias for "exc" remains in
+ "sqlalchemy" for now, it's just not patched into
sys.modules.
- orm
- Adjusted flush accounting step to occur before
the commit in the case of autocommit=True. This allows
- autocommit=True to work appropriately with
+ autocommit=True to work appropriately with
expire_on_commit=True, and also allows post-flush session
- hooks to operate in the same transactional context
+ hooks to operate in the same transactional context
as when autocommit=False. [ticket:2041]
- - Warnings generated when collection members, scalar referents
+ - Warnings generated when collection members, scalar referents
not part of the flush
[ticket:1973]
- Tuple label names in Query Improved
[ticket:1942]
- - Mapped column attributes reference the most specific
+ - Mapped column attributes reference the most specific
column first
[ticket:1892]
- - Mapping to joins with two or more same-named columns
+ - Mapping to joins with two or more same-named columns
requires explicit declaration
[ticket:1896]
- - Mapper requires that polymorphic_on column be present
+ - Mapper requires that polymorphic_on column be present
in the mapped selectable
[ticket:1875]
- - compile_mappers() renamed configure_mappers(), simplified
+ - 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()
+ (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
+ assigned, and raise StaleDataError if they don't
match. [ticket:2027]
- Session.connection(), Session.execute() accept 'bind',
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])
+ - 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
+ - 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
- Session weak_instance_dict=False is deprecated.
[ticket:1473]
- - An exception is raised in the unusual case that an
+ - 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"
+ 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]
- 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
+ ([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
+ 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
+ - 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
- sql
- Added over() function, method to FunctionElement
- classes, produces the _Over() construct which
+ classes, produces the _Over() construct which
in turn generates "window functions", i.e.
"<window function> OVER (PARTITION BY <partition by>,
ORDER BY <order by>)".
- 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`
+ available via passing a list to the `distinct`
keyword argument to select(). [ticket:1069]
- select.prefix_with() accepts multiple expressions
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 -
+ 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
- DDL() constructs now escape percent signs
[ticket:1897]
- - Table.c / MetaData.tables refined a bit, don't allow direct
+ - Table.c / MetaData.tables refined a bit, don't allow direct
mutation [ticket:1893] [ticket:1917]
- Callables passed to `bindparam()` don't get evaluated
definition, using strings as column names, as an alternative
to the creation of the index outside of the Table.
- - execution_options() on Connection accepts
+ - 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
- 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
+ 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
+ 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
+ - 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]
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
+ executions which fail before the DBAPI becomes
involved. [ticket:2015]
- - The concept of associating a ".bind" directly with a
+ - 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
+ to internal organization and is unlikely to affect any
real-world usage. [ticket:2048]
- Column.copy(), as used in table.tometadata(), copies the
- 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'
+ 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
+ This behavior makes these types more closely compatible
+ with Postgresql's VARCHAR type which is similarly unbounded
when no length is specified.
- mysql
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
+ 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
+ - 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
+ - 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
+ objects, despite passive_deletes remaining at
its default of False. [ticket:2002]
- A warning is emitted when version_id_col is specified
transformed to the empty slice -1:0 that resulted in
IndexError. [ticket:1968]
- - The mapper argument "primary_key" can be passed as a
+ - 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
+ The documentation examples that illustrated it as a
scalar value have been changed to lists.
- Added active_history flag to relationship()
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
+ in a composite key is too large, as well as too
small. [ticket:1977]
- Backport of "optimized get" fix from 0.7,
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
+ the suggestion. Also add "foreign_keys" to the
suggestion for the generic "direction" error.
- sql
i.e. "x - (y - z).label('foo')"
[ticket:1984]
- - The 'info' attribute of Column is copied during
+ - 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
+ to int, for DBAPIs such as pymssql that naively call
str() on values.
- CheckConstraint will copy its 'initially', 'deferrable',
- 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
+ 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
+ - Implemented sequence check capability for the C
+ version of RowProxy, as well as 2.7 style
"collections.Sequence" registration for RowProxy.
[ticket:1871]
parenthesize correctly, also from [ticket:1984]
- Ensured every numeric, float, int code, scalar + array,
- are recognized by psycopg2 and pg8000's "numeric"
+ 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
+ strings. Currently, the UUID type is only known to
work with psycopg2. [ticket:1956]
- - Fixed bug whereby KeyError would occur with non-ENUM
+ - 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
+ - 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
+ 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]
- 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
+ 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
+ lets float() pass right through, thereby allowing
special values such as float('inf'). [ticket:2012]
- declarative
- 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.
+ 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
+ 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
+ an object from one reference to another, with
backrefs involved, where the initiating parent
- was a subclass (with its own mapper) of the
+ 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
+ - 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
- 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
+ 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
- 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
+ a class attribute with a different keyname as the
actual column name. [ticket:1935]
- Added an assertion during flush which ensures
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
+ 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
+ determined and the "committed" state may not be
available. [ticket:1910]
- A new flag on relationship(), load_on_pending, allows
- Another new flag on relationship(), cascade_backrefs,
disables the "save-update" cascade when the event was
- initiated on the "reverse" side of a bidirectional
+ 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
+ while still allowing the forward collection to
cascade. We *might* default this to False in 0.7.
- Slight improvement to the behavior of
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
+ 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.
of the query only, instead of repeatedly. May make
some more adjustments to this.
- - scoped_session emits a warning when configure() is
+ - scoped_session emits a warning when configure() is
called if a Session is already present (checks only the
current thread) [ticket:1924]
- sql
- Fixed bug in TypeDecorator whereby the dialect-specific
- type was getting pulled in to generate the DDL for a
+ 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
the desired effect.
- TypeDecorator.load_dialect_impl() returns "self.impl" by
- default, i.e. not the dialect implementation type of
+ 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
+ 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
+ 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
+ - 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
+ - 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
+ that column is compiled before its name is
assigned.
- as_scalar(), label() can be called on a selectable
not the singleton NULLTYPE instance. [ticket:1907]
- declarative
- - @classproperty (soon/now @declared_attr) takes effect for
- __mapper_args__, __table_args__, __tablename__ on
+ - @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,
+ "marker" that's specific to declararative,
not just an attribute technique. [ticket:1915]
- Fixed bug whereby columns on a mixin wouldn't propagate
different than that of the column. [ticket:1930],
[ticket:1931].
- - A mixin can now specify a column that overrides
+ - A mixin can now specify a column that overrides
a column of the same name associated with a superclass.
Thanks to Oystein Haaland.
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)"
+ a connection is first used is now "BEGIN (implicit)"
to emphasize that DBAPI has no explicit begin().
- - added "views=True" option to metadata.reflect(),
+ - 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
+ - engine_from_config() now accepts 'debug' for
'echo', 'echo_pool', 'force' for 'convert_unicode',
boolean values for 'use_native_unicode'.
[ticket:1899]
- 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
+ - 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
+ - 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
+ 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]
- Fixed bug where aliasing of tables with "schema" would
fail to compile properly. [ticket:1943]
- - Rewrote the reflection of indexes to use sys.
+ - 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
+ 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.
+ - *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
+ 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.
=====
- orm
- The name ConcurrentModificationError has been
- changed to StaleDataError, and descriptive
+ 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
+ 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
+ which now pre-buffer before returning an
+ iterable. This because asyncrhonous gc
can remove items via the gc thread at any time.
[ticket:1891]
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
+ 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.
[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
+ 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
+ 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
- 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
+ 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"
+ 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
+ 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.
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
+ 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,
+ A warning is now emitted instead of an error,
and the mapping succeeds. [ticket:1877]
- Moving an o2m object from one collection to
unless we know it was a PK switch that
triggered the change. [ticket:1856]
- - The value of version_id_col can be changed
+ - 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
+ 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
+ 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
+ - 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
text() or literal(). [ticket:1863]
- Similarly, for relationship(), foreign_keys,
- remote_side, order_by - all column-based
+ 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
+ - 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
- 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
+ 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
+ - object_session() raises the proper
UnmappedInstanceError when presented with an
unmapped instance. [ticket:1881]
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
+ - 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
+ if versioning on a col that was formerly
NULL.
- sql
not an Executable (unless you were an alias(), see
previous note).
- - Added basic math expression coercion for
+ - Added basic math expression coercion for
Numeric->Integer,
so that resulting type is Numeric regardless
of the direction of the expression.
"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
+ 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
+ - The generated index name also is based on
a "max index name length" attribute which is
- separate from the "max identifier length" -
+ 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
+ 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,
+ - Added full description of parent table/column,
target table/column in error message raised when
ForeignKey can't resolve target.
- 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
+ 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
+ operations which depend on the identity of the
_Labels themselves to return the correct result
- fixes ORM bug [ticket:1852].
- Calling fetchone() or similar on a result that
has already been exhausted, has been closed,
- or is not a result-returning result now
+ or is not a result-returning result now
raises ResourceClosedError, a subclass of
InvalidRequestError, in all cases, regardless
of backend. Previously, some DBAPIs would
- 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
+ as psycopg2 resets the isolation level on each new
transaction otherwise.
- mssql
pymssql backend.
- firebird
- - Fixed bug whereby a column default would fail to
+ - Fixed bug whereby a column default would fail to
reflect if the "default" keyword were lower case.
- oracle
- examples
- The beaker_caching example has been reorgnized
- such that the Session, cache manager,
+ 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
+ "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
+ 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
+ - 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
+ - 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
+ 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",
+ - 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
+ 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
+ the Query will return. Can be helpful for
building GUIs on top of ORM queries.
- mysql
- - The _extract_error_code() method now works
+ - 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
+ 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.
+ - More tweaks to cx_oracle Decimal handling.
"Ambiguous" numerics with no decimal place
- are coerced to int at the connection handler
+ are coerced to int at the connection handler
level. The advantage here is that ints
- come back as ints without SQLA type
+ 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
+ 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
=====
- orm
- Query.join() will check for a call of the
- form query.join(target, clause_expression),
+ 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
+ - 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
- the post_update feature of relationship() has been
reworked architecturally to integrate more closely
- with the new 0.6 unit of work. The motivation
+ 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
+ UPDATE statement, rather than one UPDATE
statement per column per row. Multiple row
- updates are also batched into executemany()s as
+ updates are also batched into executemany()s as
possible, while maintaining consistent row ordering.
- Query.statement, Query.subquery(), etc. now transfer
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
+ 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
+ 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
+ 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.
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,
+ is emitted once as per the warning filter settings,
and large string values don't pollute the output.
[ticket:1822]
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
+ is passed through render_literal_value(), which may
implement escaping of backslashes. [ticket:1400]
- Fixed bug in Enum type which blew away native_enum
- 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
+ _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
- 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
+ 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 -
+ 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
+ - MySQL dialect doesn't emit CAST() for MySQL version
detected < 4.0.2. This allows the unicode
check on connect to proceed. [ticket:1826]
- 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
+ is derived from detecting the value of
NO_BACKSLASH_ESCAPES. [ticket:1400]
- oracle:
- 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
+ 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
+ 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
+ - Fixed incorrect signature in do_execute(), error
introduced in 0.6.1. [ticket:1823]
- Firebird dialect adds CHAR, VARCHAR types which
"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
+ - 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
[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
+ 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]
- 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
+ user-defined compiler is specific to certain
backends and compilation for a different backend
is invoked. [ticket:1838]
- 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
+ decorators so that Sphinx documentation picks up
+ these attributes and methods, such as
ResultProxy.inserted_primary_key. [ticket:1830]
fail during deserialize where parent InstanceState not
yet unserialized. [ticket:1802]
- - Added internal warning in case an instance without a
+ - 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
+ 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 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
[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
+ 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
[ticket:1571]
- Fixed bug in connection pool cursor wrapper whereby if a
- cursor threw an exception on close(), the logging of the
+ 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
+ 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
+ - func.XXX() doesn't inadvertently resolve to non-Function
classes (e.g. fixes func.text()). [ticket:1798]
- engines
- 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
+ - Engine gains an "execution_options" argument and
+ update_execution_options() method, which will apply to
all connections generated by this engine.
- mysql
parenthesis, on MySQL. [ticket:1794]
- sqlite
- - Fixed concatenation of constraints when "PRIMARY KEY"
+ - 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
+ 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
+ - 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
+ - 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
+ - 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
[ticket:1815]
- firebird
- - Added a label to the query used within has_table() and
+ - 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
+ - Added integer coercion to the "type_conv" attribute when
passed via query string, so that it is properly interpreted
by Kinterbasdb. [ticket:1779]
- 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
+ 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,
+ [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
+ 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
+ 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
+ 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
+ - 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()
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
+ - 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
+ - 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
+ 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
+ insert() and update() constructs when flushing lists of
objects of all the same class, thereby avoiding redundant
- compilation per individual INSERT/UPDATE within an
+ 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
+ have been underscored (i.e. are private), signature has
changed.
- engines
- 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
+ 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
+ - 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
loop for expressions with two NULL types.
- Fixed bug in execution_options() feature whereby the existing
- Transaction and other state information from the parent
+ 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
+ - 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-
+ 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,
+ 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
- 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
+ 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
+ - 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
+ - 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
+ - Repaired missing import in psycopg2._PGNumeric type when
unknown numeric is received.
- - psycopg2/pg8000 dialects now aware of REAL[], FLOAT[],
+ - psycopg2/pg8000 dialects now aware of REAL[], FLOAT[],
DOUBLE_PRECISION[], NUMERIC[] return types without
raising an exception.
- 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
+ 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
+ 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'
+ 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
+ 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
+ To re-enable on a per-execution basis, the
'enable_rowcount=True' execution option may be used.
- examples
========
- orm
- - Major feature: Added new "subquery" loading capability to
+ - 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
+ 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..)",
+ 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
+ - 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
+ - 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/
- 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
+ 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
+ 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
+ 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
+ - 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
+ version of add_column(col). add_column(col) is future
deprecated.
- - Query.join() will detect if the end result will be
+ - 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
- 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
+ "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
+ - 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.
+ "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
+ argument 'precision' to both. 'precision' and
+ 'timezone' are correctly reflected for both TIME and
TIMEZONE types. [ticket:997]
- mysql
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.CHAR_LENGTH instead of
ALL_TAB_COLUMNS.DATA_LENGTH. Both of these behaviors take
- effect when the server version is 9 or higher - for
+ 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
+ - 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
+ - Using @classdecorator and similar on mixins to define
__tablename__, __table_args__, etc. now works if
- the method references attributes on the ultimate
+ the method references attributes on the ultimate
subclass. [ticket:1749]
- - relationships and columns with foreign keys aren't
+ - 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
+ sqlalchemy.ext.horizontal_shard. The old import
works with a deprecation warning.
0.6beta2
- orm
- The official name for the relation() function is now
relationship(), to eliminate confusion over the relational
- algebra term. relation() however will remain available
+ 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
- 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
+ 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
+ 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
- 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
+ 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
+ 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()
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
+ that is present in the identity map with a different class
than the one requested, i.e. when using polymorphic loading.
[ticket:1727]
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
+ - 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
+ - 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.
- 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,
+ - 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()
- 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
+ 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
+ - 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
+ - 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
including their ddl listener and other event callables.
[ticket:1694] [ticket:1698]
- - Some platforms will now interpret certain literal values
+ - 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
+ 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
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
+ 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.
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
+ 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
+ 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
+ - 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
+ 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
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
+ 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
+ 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
+ the coerce_compared_value() method. Also part of
[ticket:1683].
- - Made sqlalchemy.sql.expressions.Executable part of public
+ - 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
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
+ 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
+ - 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
+ - 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]
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
+ 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
+ - 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
+ 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
+ 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
+ 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
- threadlocal engine wasn't properly closing the connection
upon close() - fixed that.
- - Transaction object doesn't rollback or commit if it isn't
+ - 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,
+ - 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.
- 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
+ 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
+ - 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]
[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
+ - 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.
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
+ 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,
[ticket:1732]
- mysql
- - Fixed reflection bug whereby when COLLATE was present,
+ - Fixed reflection bug whereby when COLLATE was present,
nullable flag and server defaults would not be reflected.
[ticket:1655]
- 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
+ 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
- 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,
+ type *will* still call value.date() on incoming values,
however. When reflecting a table, the reflected type
will be 'DATE'.
which is more or less equivalent on that platform.
[ticket:1712]
- - Added support for rendering and reflecting
+ - Added support for rendering and reflecting
TIMESTAMP WITH TIME ZONE, i.e. TIMESTAMP(timezone=True).
[ticket:651]
- 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
+ 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
+ compatible with the "func.current_date()", which
will be returned as a string. [ticket:1685]
- sybase
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
+ - 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.
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
+ 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.
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
+ - 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
+ - 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),
+ 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
- the "named tuple" objects returned when iterating a
Query() are now pickleable.
- - mapping to a select() construct now requires that you
+ - 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
+ - query.join() has been reworked to provide more consistent
behavior and more flexibility (includes [ticket:1537])
- - query.select_from() accepts multiple clauses to produce
+ - query.select_from() accepts multiple clauses to produce
multiple comma separated entries within the FROM clause.
Useful when selecting from multiple-homed join() clauses.
where one or more of the primary key values are None.
[ticket:1135]
- - query.from_self(), query.union(), others which do a
+ - 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
+ 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]
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
+ - 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.
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
+ 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
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.
+ "stream_results" is psycopg2.
- Query.yield_per() will set the "stream_results" statement
option automatically.
* '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
+ * '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
+ 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
+ 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 "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
+ * 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
+ 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.
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
+ 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
+ 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
+ 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(),
specified.
- union(), intersect(), except() and other "compound" types
- of statements have more consistent behavior w.r.t.
- parenthesizing. Each compound element embedded within
+ 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
+ as SQLite doesn't like a statement to start with
parenthesis. However, Postgresql in particular has
- precedence rules regarding INTERSECT, and it is
+ 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 -
- 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
+ bind parameters will circumvent the usual route to those
keys showing up in the VALUES or SET clause of the generated
SQL. [ticket:1579]
- 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
+ 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
+ rely upon the database to report problems with
col mismatch.
- - User-defined "default" and "onupdate" callables which
- accept a context should now call upon
+ - 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
+ 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
+ - 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
- 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
+ "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.
default options for the Connection. See the note in "engines".
- Deprecated or removed:
- * "scalar" flag on select() is removed, use
+ * "scalar" flag on select() is removed, use
select.as_scalar().
* "shortname" attribute on bindparam() is removed.
- * postgres_returning, firebird_returning flags on
+ * 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
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
+ 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
+ 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
+ text() also have .execution_options() as well as
ORM Query().
- - fixed the import for entrypoint-driven dialects to
+ - fixed the import for entrypoint-driven dialects to
not rely upon silly tb_info trick to determine import
error status. [ticket:1630]
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
+ 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
+ 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"
logging. `echo_pool` can be False, None, True or "debug"
the same way as `echo` works.
- - All pyodbc-dialects now support extra pyodbc-specific
+ - All pyodbc-dialects now support extra pyodbc-specific
kw arguments 'ansi', 'unicode_results', 'autocommit'.
[ticket:1621]
- - the "threadlocal" engine has been rewritten and simplified
+ - the "threadlocal" engine has been rewritten and simplified
and now supports SAVEPOINT operations.
- deprecated or removed
- * result.last_inserted_ids() is deprecated. Use
+ * 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,
+ *args and **kwargs which are passed to the given callable,
as well as the operating connection.
- schema
copy() all their public keyword arguments. [ticket:1605]
- Reflection/Inspection
- - Table reflection has been expanded and generalized into
+ - 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,
indexes, etc.
- Views are now reflectable as ordinary Table objects. The same
- Table constructor is used, with the caveat that "effective"
+ 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.
- CreateSequence()
- DropSequence()
- These support "on" and "execute-at()" just like plain DDL()
- does. User-defined DDLElement subclasses can be created and
+ 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
"ddl" - the DDLElement object itself.
"event" - the string event name.
- "target" - previously "schema_item", the Table or
+ "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
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
+ - the "schema_item" attribute of DDL has been renamed to
"target".
- dialect refactor
i.e. "mysql+mysqldb://scott:tiger@localhost/test". See
the 0.6 documentation for examples.
- - the setuptools entrypoint for external dialects is now
+ - the setuptools entrypoint for external dialects is now
called "sqlalchemy.dialects".
- the "owner" keyword argument is removed from Table. Use
- dialects receive a visit_pool event have an opportunity
to establish pool listeners.
- - cached TypeEngine classes are cached per-dialect class
+ - 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
+ new types, which preserves the 0.5 behavior of
get_col_spec().
- - The result_processor() method of all type classes now
+ - 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
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
+ 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]
"postgres_where" names still work with a
deprecation warning.
- - "postgresql_where" now accepts SQL expressions which
+ - "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
+ 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
+ to issue the appropriate CREATE TYPE/DROP TYPE
commands as needed, supports unicode labels, supports
reflection. [ticket:1511]
- - INTERVAL supports an optional "precision" argument
+ - 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
+ 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"
+ 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
+ - 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
connection. [ticket:1619]
- mysql
- - New dialects: oursql, a new native dialect,
+ - 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
+ 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.
- 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
+ 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
- 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"
+ 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]
uses JOIN/OUTERJOIN.
- added native INTERVAL type to the dialect. This supports
- only the DAY TO SECOND interval type so far due to lack
+ 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
+ - 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
NUMBER(19) [ticket:1125]
- "case sensitivity" feature will detect an all-lowercase
- case-sensitive column name during reflect and add
+ case-sensitive column name during reflect and add
"quote=True" to the generated Column, so that proper
quoting is maintained.
version-dependent behavior.
- "case sensitivity" feature will detect an all-lowercase
- case-sensitive column name during reflect and add
+ case-sensitive column name during reflect and add
"quote=True" to the generated Column, so that proper
quoting is maintained.
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
+ primary key column when generating DDL. Will prevent generation of
a separate PRIMARY KEY constraint. [ticket:1016]
- new dialects
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
+ 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
+ for dialect authors is in
lib/sqlalchemy/dialects/type_migration_guidelines.txt .
- Types no longer make any guesses as to default
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
+ 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
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.
+ 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
+ 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
+ the dialect itself if the type is not a standard SQL
type. This means reflection now returns more accurate
information about reflected types.
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
+ - 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.
+ 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]
- AbstractType.get_search_list() is removed - the games
that was used for are no longer necessary.
- - Added a generic BigInteger type, compiles to
+ - Added a generic BigInteger type, compiles to
BIGINT or NUMBER(19). [ticket:1125]
-ext
not needed for sqlsoup's usage paradigm and it gets in the
way of a column that is actually named 'query'.
- - The signature of the proxy_factory callable passed to
- association_proxy is now (lazy_collection, creator,
+ - 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.
- 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
+ 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.
Postgresql.
implicit_returning
- use RETURNING or equivalent during INSERT execution in order to load
+ use RETURNING or equivalent during INSERT execution in order to load
newly generated primary keys and other column defaults in one execution,
which are then available via inserted_primary_key.
- If an insert statement has returning() specified explicitly,
+ If an insert statement has returning() specified explicitly,
the "implicit" functionality is not used and inserted_primary_key
will not be available.
Allows dialects to configure options based on server version info or
other properties.
- The connection passed here is a SQLAlchemy Connection object,
+ The connection passed here is a SQLAlchemy Connection object,
with full capabilities.
The initalize() method of the base dialect should be called via
set) is specified, limit the autoload to the given column
names.
- The default implementation uses the
- :class:`~sqlalchemy.engine.reflection.Inspector` interface to
+ The default implementation uses the
+ :class:`~sqlalchemy.engine.reflection.Inspector` interface to
provide the output, building upon the granular table/column/
constraint etc. methods of :class:`.Dialect`.
raise NotImplementedError()
def normalize_name(self, name):
- """convert the given name to lowercase if it is detected as
+ """convert the given name to lowercase if it is detected as
case insensitive.
this method is only used if the dialect defines
raise NotImplementedError()
def _get_default_schema_name(self, connection):
- """Return the string name of the currently selected schema from
+ """Return the string name of the currently selected schema from
the given connection.
This is used by the default implementation to populate the
raise NotImplementedError()
def do_begin(self, connection):
- """Provide an implementation of *connection.begin()*, given a
+ """Provide an implementation of *connection.begin()*, given a
DB-API connection."""
raise NotImplementedError()
def do_rollback(self, connection):
- """Provide an implementation of *connection.rollback()*, given
+ """Provide an implementation of *connection.rollback()*, given
a DB-API connection."""
raise NotImplementedError()
raise NotImplementedError()
def do_commit(self, connection):
- """Provide an implementation of *connection.commit()*, given a
+ """Provide an implementation of *connection.commit()*, given a
DB-API connection."""
raise NotImplementedError()
def connect(self):
"""return a callable which sets up a newly created DBAPI connection.
- The callable accepts a single argument "conn" which is the
+ The callable accepts a single argument "conn" which is the
DBAPI connection itself. It has no return value.
This is used to set dialect-wide per-connection options such as
raise NotImplementedError()
def handle_dbapi_exception(self, e):
- """Receive a DBAPI exception which occurred upon execute, result
+ """Receive a DBAPI exception which occurred upon execute, result
fetch, etc."""
raise NotImplementedError()
def should_autocommit_text(self, statement):
- """Parse the given textual statement and return True if it refers to
+ """Parse the given textual statement and return True if it refers to
a "committable" statement"""
raise NotImplementedError()
def get_rowcount(self):
"""Return the DBAPI ``cursor.rowcount`` value, or in some
cases an interpreted value.
-
+
See :attr:`.ResultProxy.rowcount` for details on this.
"""
:param statement: ``ClauseElement`` to be compiled.
- :param bind: Optional Engine or Connection to compile this
+ :param bind: Optional Engine or Connection to compile this
statement against.
"""
return e._execute_compiled(self, multiparams, params)
def scalar(self, *multiparams, **params):
- """Execute this compiled object and return the result's
+ """Execute this compiled object and return the result's
scalar value."""
return self.execute(*multiparams, **params).scalar()
"""Return a :class:`.Connection` object.
Depending on context, this may be ``self`` if this object
- is already an instance of :class:`.Connection`, or a newly
+ is already an instance of :class:`.Connection`, or a newly
procured :class:`.Connection` if this object is an instance
of :class:`.Engine`.
context.
Depending on context, this may be ``self`` if this object
- is already an instance of :class:`.Connection`, or a newly
+ is already an instance of :class:`.Connection`, or a newly
procured :class:`.Connection` if this object is an instance
of :class:`.Engine`.
"""
raise NotImplementedError()
- def _run_visitor(self, visitorcallable, element,
+ def _run_visitor(self, visitorcallable, element,
**kwargs):
raise NotImplementedError()
"""
return self.engine._connection_cls(
- self.engine,
+ self.engine,
self.__connection, _branch=True)
def _clone(self):
self.close()
def execution_options(self, **opt):
- """ Set non-SQL options for the connection which take effect
+ """ Set non-SQL options for the connection which take effect
during execution.
The method returns a copy of this :class:`.Connection` which references
:meth:`.Connection.execution_options` accepts all options as those
accepted by :meth:`.Executable.execution_options`. Additionally,
- it includes options that are applicable only to
+ it includes options that are applicable only to
:class:`.Connection`.
:param autocommit: Available on: Connection, statement.
- When True, a COMMIT will be invoked after execution
+ When True, a COMMIT will be invoked after execution
when executed in 'autocommit' mode, i.e. when an explicit
transaction is not begun on the connection. Note that DBAPI
connections by default are always in a transaction - SQLAlchemy uses
:param compiled_cache: Available on: Connection.
A dictionary where :class:`.Compiled` objects
- will be cached when the :class:`.Connection` compiles a clause
+ will be cached when the :class:`.Connection` compiles a clause
expression into a :class:`.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,
+ names within the VALUES or SET clause of an INSERT or UPDATE,
as well as the "batch" mode for an INSERT or UPDATE statement.
The format of this dictionary is not guaranteed to stay the
same in future releases.
- Note that the ORM makes use of its own "compiled" caches for
+ Note that the ORM makes use of its own "compiled" caches for
some operations, including flush operations. The caching
used by the ORM internally supersedes a cache dictionary
specified here.
the lifespan of this connection. Valid values include
those string values accepted by the ``isolation_level``
parameter passed to :func:`.create_engine`, and are
- database specific, including those for :ref:`sqlite_toplevel`,
+ database specific, including those for :ref:`sqlite_toplevel`,
:ref:`postgresql_toplevel` - see those dialect's documentation
for further info.
- Note that this option necessarily affects the underlying
- DBAPI connection for the lifespan of the originating
- :class:`.Connection`, and is not per-execution. This
- setting is not removed until the underlying DBAPI connection
+ Note that this option necessarily affects the underlying
+ DBAPI connection for the lifespan of the originating
+ :class:`.Connection`, and is not per-execution. This
+ setting is not removed until the underlying DBAPI connection
is returned to the connection pool, i.e.
the :meth:`.Connection.close` method is called.
- :param no_parameters: When ``True``, if the final parameter
- list or dictionary is totally empty, will invoke the
+ :param no_parameters: When ``True``, if the final parameter
+ list or dictionary is totally empty, will invoke the
statement on the cursor as ``cursor.execute(statement)``,
not passing the parameter collection at all.
Some DBAPIs such as psycopg2 and mysql-python consider
- percent signs as significant only when parameters are
+ percent signs as significant only when parameters are
present; this option allows code to generate SQL
containing percent signs (and possibly other characters)
that is neutral regarding whether it's executed by the DBAPI
- or piped into a script that's later invoked by
+ or piped into a script that's later invoked by
command line tools.
.. versionadded:: 0.7.6
:param stream_results: Available on: Connection, statement.
- Indicate to the dialect that results should be
+ Indicate to the dialect that results should be
"streamed" and not pre-buffered, if possible. This is a limitation
of many DBAPIs. The flag is currently understood only by the
psycopg2 dialect.
return c
def _set_isolation_level(self):
- self.dialect.set_isolation_level(self.connection,
+ self.dialect.set_isolation_level(self.connection,
self._execution_options['isolation_level'])
self.connection._connection_record.finalize_callback = \
self.dialect.reset_isolation_level
return self
def invalidate(self, exception=None):
- """Invalidate the underlying DBAPI connection associated with
+ """Invalidate the underlying DBAPI connection associated with
this Connection.
The underlying DB-API connection is literally closed (if
Nested calls to :meth:`.begin` on the same :class:`.Connection`
will return new :class:`.Transaction` objects that represent
- an emulated transaction within the scope of the enclosing
+ an emulated transaction within the scope of the enclosing
transaction, that is::
-
+
trans = conn.begin() # outermost transaction
- trans2 = conn.begin() # "nested"
+ trans2 = conn.begin() # "nested"
trans2.commit() # does nothing
trans.commit() # actually commits
-
- Calls to :meth:`.Transaction.commit` only have an effect
+
+ Calls to :meth:`.Transaction.commit` only have an effect
when invoked via the outermost :class:`.Transaction` object, though the
:meth:`.Transaction.rollback` method of any of the
:class:`.Transaction` objects will roll back the
transaction.
See also:
-
+
:meth:`.Connection.begin_nested` - use a SAVEPOINT
-
+
:meth:`.Connection.begin_twophase` - use a two phase /XID transaction
-
+
:meth:`.Engine.begin` - context manager available from :class:`.Engine`.
"""
still controls the overall ``commit`` or ``rollback`` of the
transaction of a whole.
- See also :meth:`.Connection.begin`,
+ See also :meth:`.Connection.begin`,
:meth:`.Connection.begin_twophase`.
"""
:class:`.Transaction`, also provides a :meth:`~.TwoPhaseTransaction.prepare`
method.
- :param xid: the two phase transaction id. If not supplied, a
+ :param xid: the two phase transaction id. If not supplied, a
random id will be generated.
- See also :meth:`.Connection.begin`,
+ See also :meth:`.Connection.begin`,
:meth:`.Connection.begin_twophase`.
"""
def execute(self, object, *multiparams, **params):
"""Executes the a SQL statement construct and returns a :class:`.ResultProxy`.
- :param object: The statement to be executed. May be
+ :param object: The statement to be executed. May be
one of:
* a plain string
* any :class:`.ClauseElement` construct that is also
- a subclass of :class:`.Executable`, such as a
+ a subclass of :class:`.Executable`, such as a
:func:`~.expression.select` construct
* a :class:`.FunctionElement`, such as that generated
by :attr:`.func`, will be automatically wrapped in
dictionaries passed to \*multiparams::
conn.execute(
- table.insert(),
+ table.insert(),
{"id":1, "value":"v1"},
{"id":2, "value":"v2"}
)
table.insert(), id=1, value="v1"
)
- In the case that a plain SQL string is passed, and the underlying
+ In the case that a plain SQL string is passed, and the underlying
DBAPI accepts positional bind parameters, a collection of tuples
or individual values in \*multiparams may be passed::
-
+
conn.execute(
"INSERT INTO table (id, value) VALUES (?, ?)",
(1, "v1"), (2, "v2")
)
Note above, the usage of a question mark "?" or other
- symbol is contingent upon the "paramstyle" accepted by the DBAPI
+ symbol is contingent upon the "paramstyle" accepted by the DBAPI
in use, which may be any of "qmark", "named", "pyformat", "format",
- "numeric". See `pep-249 <http://www.python.org/dev/peps/pep-0249/>`_
+ "numeric". See `pep-249 <http://www.python.org/dev/peps/pep-0249/>`_
for details on paramstyle.
To execute a textual SQL statement which uses bound parameters in a
for c in type(object).__mro__:
if c in Connection.executors:
return Connection.executors[c](
- self,
+ self,
object,
- multiparams,
+ multiparams,
params)
else:
raise exc.InvalidRequestError(
def _execute_function(self, func, multiparams, params):
"""Execute a sql.FunctionElement object."""
- return self._execute_clauseelement(func.select(),
+ return self._execute_clauseelement(func.select(),
multiparams, params)
def _execute_default(self, default, multiparams, params):
self.close()
if self._has_events:
- self.engine.dispatch.after_execute(self,
+ self.engine.dispatch.after_execute(self,
default, multiparams, params, ret)
return ret
ret = self._execute_context(
dialect,
dialect.execution_ctx_cls._init_ddl,
- compiled,
+ compiled,
None,
compiled
)
if self._has_events:
- self.engine.dispatch.after_execute(self,
+ self.engine.dispatch.after_execute(self,
ddl, multiparams, params, ret)
return ret
compiled_sql = self._execution_options['compiled_cache'][key]
else:
compiled_sql = elem.compile(
- dialect=dialect, column_keys=keys,
+ dialect=dialect, column_keys=keys,
inline=len(distilled_params) > 1)
self._execution_options['compiled_cache'][key] = compiled_sql
else:
compiled_sql = elem.compile(
- dialect=dialect, column_keys=keys,
+ dialect=dialect, column_keys=keys,
inline=len(distilled_params) > 1)
ret = self._execute_context(
dialect,
dialect.execution_ctx_cls._init_compiled,
- compiled_sql,
+ compiled_sql,
distilled_params,
compiled_sql, distilled_params
)
if self._has_events:
- self.engine.dispatch.after_execute(self,
+ self.engine.dispatch.after_execute(self,
elem, multiparams, params, ret)
return ret
ret = self._execute_context(
dialect,
dialect.execution_ctx_cls._init_compiled,
- compiled,
+ compiled,
parameters,
compiled, parameters
)
if self._has_events:
- self.engine.dispatch.after_execute(self,
+ self.engine.dispatch.after_execute(self,
compiled, multiparams, params, ret)
return ret
ret = self._execute_context(
dialect,
dialect.execution_ctx_cls._init_statement,
- statement,
+ statement,
parameters,
statement, parameters
)
if self._has_events:
- self.engine.dispatch.after_execute(self,
+ self.engine.dispatch.after_execute(self,
statement, multiparams, params, ret)
return ret
- def _execute_context(self, dialect, constructor,
- statement, parameters,
+ def _execute_context(self, dialect, constructor,
+ statement, parameters,
*args):
"""Create an :class:`.ExecutionContext` and execute, returning
a :class:`.ResultProxy`."""
context = constructor(dialect, self, conn, *args)
except Exception, e:
- self._handle_dbapi_exception(e,
- str(statement), parameters,
+ self._handle_dbapi_exception(e,
+ str(statement), parameters,
None, None)
raise
if self._has_events:
for fn in self.engine.dispatch.before_cursor_execute:
statement, parameters = \
- fn(self, cursor, statement, parameters,
+ fn(self, cursor, statement, parameters,
context, context.executemany)
if self._echo:
self.engine.logger.info(statement)
- self.engine.logger.info("%r",
+ self.engine.logger.info("%r",
sql_util._repr_params(parameters, batches=10))
try:
if context.executemany:
self.dialect.do_executemany(
- cursor,
- statement,
- parameters,
+ cursor,
+ statement,
+ parameters,
context)
elif not parameters and context.no_parameters:
self.dialect.do_execute_no_params(
- cursor,
- statement,
+ cursor,
+ statement,
context)
else:
self.dialect.do_execute(
- cursor,
- statement,
- parameters,
+ cursor,
+ statement,
+ parameters,
context)
except Exception, e:
self._handle_dbapi_exception(
- e,
- statement,
- parameters,
- cursor,
+ e,
+ statement,
+ parameters,
+ cursor,
context)
raise
if self._has_events:
- self.engine.dispatch.after_cursor_execute(self, cursor,
- statement,
- parameters,
- context,
+ self.engine.dispatch.after_cursor_execute(self, cursor,
+ statement,
+ parameters,
+ context,
context.executemany)
if context.compiled:
elif not context._is_explicit_returning:
result.close(_autoclose_connection=False)
elif result._metadata is None:
- # no results, get rowcount
+ # no results, get rowcount
# (which requires open cursor on some drivers
# such as kintersbasdb, mxodbc),
result.rowcount
This method is used by DefaultDialect for special-case
executions, such as for sequences and column defaults.
- The path of statement execution in the majority of cases
+ The path of statement execution in the majority of cases
terminates at _execute_context().
"""
self.engine.logger.info("%r", parameters)
try:
self.dialect.do_execute(
- cursor,
- statement,
+ cursor,
+ statement,
parameters)
except Exception, e:
self._handle_dbapi_exception(
- e,
- statement,
- parameters,
+ e,
+ statement,
+ parameters,
cursor,
None)
raise
if isinstance(e, (SystemExit, KeyboardInterrupt)):
raise
- def _handle_dbapi_exception(self,
- e,
- statement,
- parameters,
- cursor,
+ def _handle_dbapi_exception(self,
+ e,
+ statement,
+ parameters,
+ cursor,
context):
if getattr(self, '_reentrant_error', False):
# Py3K
- #raise exc.DBAPIError.instance(statement, parameters, e,
+ #raise exc.DBAPIError.instance(statement, parameters, e,
# self.dialect.dbapi.Error) from e
# Py2K
- raise exc.DBAPIError.instance(statement,
- parameters,
- e,
+ raise exc.DBAPIError.instance(statement,
+ parameters,
+ e,
self.dialect.dbapi.Error), \
None, sys.exc_info()[2]
# end Py2K
if should_wrap and context:
if self._has_events:
- self.engine.dispatch.dbapi_error(self,
- cursor,
- statement,
- parameters,
- context,
+ self.engine.dispatch.dbapi_error(self,
+ cursor,
+ statement,
+ parameters,
+ context,
e)
context.handle_dbapi_exception(e)
# Py3K
#raise exc.DBAPIError.instance(
- # statement,
- # parameters,
- # e,
+ # statement,
+ # parameters,
+ # e,
# self.dialect.dbapi.Error,
# connection_invalidated=is_disconnect) \
# from e
# Py2K
raise exc.DBAPIError.instance(
- statement,
- parameters,
- e,
+ statement,
+ parameters,
+ e,
self.dialect.dbapi.Error,
connection_invalidated=is_disconnect), \
None, sys.exc_info()[2]
set) is specified, limit the autoload to the given column
names.
- The default implementation uses the
- :class:`.Inspector` interface to
+ The default implementation uses the
+ :class:`.Inspector` interface to
provide the output, building upon the granular table/column/
constraint etc. methods of :class:`.Dialect`.
def transaction(self, callable_, *args, **kwargs):
"""Execute the given function within a transaction boundary.
- The function is passed this :class:`.Connection`
+ The function is passed this :class:`.Connection`
as the first argument, followed by the given \*args and \**kwargs,
e.g.::
-
+
def do_something(conn, x, y):
conn.execute("some statement", {'x':x, 'y':y})
conn.transaction(do_something, 5, 10)
The operations inside the function are all invoked within the
- context of a single :class:`.Transaction`.
- Upon success, the transaction is committed. If an
+ context of a single :class:`.Transaction`.
+ Upon success, the transaction is committed. If an
exception is raised, the transaction is rolled back
before propagating the exception.
The :meth:`.transaction` method is superseded by
the usage of the Python ``with:`` statement, which can
be used with :meth:`.Connection.begin`::
-
+
with conn.begin():
conn.execute("some statement", {'x':5, 'y':10})
-
+
As well as with :meth:`.Engine.begin`::
-
+
with engine.begin() as conn:
conn.execute("some statement", {'x':5, 'y':10})
-
+
See also:
-
- :meth:`.Engine.begin` - engine-level transactional
+
+ :meth:`.Engine.begin` - engine-level transactional
context
-
+
:meth:`.Engine.transaction` - engine-level version of
:meth:`.Connection.transaction`
The given \*args and \**kwargs are passed subsequent
to the :class:`.Connection` argument.
- This function, along with :meth:`.Engine.run_callable`,
+ This function, along with :meth:`.Engine.run_callable`,
allows a function to be run with a :class:`.Connection`
or :class:`.Engine` object without the need to know
which one is being dealt with.
class Transaction(object):
"""Represent a database transaction in progress.
- The :class:`.Transaction` object is procured by
+ The :class:`.Transaction` object is procured by
calling the :meth:`~.Connection.begin` method of
:class:`.Connection`::
trans.commit()
The object provides :meth:`.rollback` and :meth:`.commit`
- methods in order to control transaction boundaries. It
- also implements a context manager interface so that
- the Python ``with`` statement can be used with the
+ methods in order to control transaction boundaries. It
+ also implements a context manager interface so that
+ the Python ``with`` statement can be used with the
:meth:`.Connection.begin` method::
with connection.begin():
class Engine(Connectable, log.Identified):
"""
- Connects a :class:`~sqlalchemy.pool.Pool` and
- :class:`~sqlalchemy.engine.base.Dialect` together to provide a source
+ Connects a :class:`~sqlalchemy.pool.Pool` and
+ :class:`~sqlalchemy.engine.base.Dialect` together to provide a source
of database connectivity and behavior.
- An :class:`.Engine` object is instantiated publicly using the
+ An :class:`.Engine` object is instantiated publicly using the
:func:`~sqlalchemy.create_engine` function.
See also:
_has_events = False
_connection_cls = Connection
- def __init__(self, pool, dialect, url,
+ def __init__(self, pool, dialect, url,
logging_name=None, echo=None, proxy=None,
execution_options=None
):
dispatch = event.dispatcher(events.ConnectionEvents)
def update_execution_options(self, **opt):
- """Update the default execution_options dictionary
+ """Update the default execution_options dictionary
of this :class:`.Engine`.
The given keys/values in \**opt are added to the
- default execution options that will be used for
+ default execution options that will be used for
all connections. The initial contents of this dictionary
can be sent via the ``execution_options`` parameter
to :func:`.create_engine`.
A new connection pool is created immediately after the old one has
been disposed. This new pool, like all SQLAlchemy connection pools,
- does not make any actual connections to the database until one is
+ does not make any actual connections to the database until one is
first requested.
This method has two general use cases:
* When a dropped connection is detected, it is assumed that all
- connections held by the pool are potentially dropped, and
+ connections held by the pool are potentially dropped, and
the entire pool is replaced.
- * An application may want to use :meth:`dispose` within a test
+ * An application may want to use :meth:`dispose` within a test
suite that is creating multiple engines.
It is critical to note that :meth:`dispose` does **not** guarantee
that the application will release all open database connections - only
those connections that are checked into the pool are closed.
Connections which remain checked out or have been detached from
- the engine are not affected.
+ the engine are not affected.
"""
self.pool.dispose()
- self.pool = self.pool.recreate()
+ self.pool = self.pool._replace()
@util.deprecated("0.7", "Use the create() method on the given schema "
"object directly, i.e. :meth:`.Table.create`, "
from sqlalchemy.engine import ddl
- self._run_visitor(ddl.SchemaGenerator, entity,
+ self._run_visitor(ddl.SchemaGenerator, entity,
connection=connection, **kwargs)
@util.deprecated("0.7", "Use the drop() method on the given schema "
from sqlalchemy.engine import ddl
- self._run_visitor(ddl.SchemaDropper, entity,
+ self._run_visitor(ddl.SchemaDropper, entity,
connection=connection, **kwargs)
def _execute_default(self, default):
connection.close()
@property
- @util.deprecated("0.7",
+ @util.deprecated("0.7",
"Use :attr:`~sqlalchemy.sql.expression.func` to create function constructs.")
def func(self):
return expression._FunctionGenerator(bind=self)
- @util.deprecated("0.7",
+ @util.deprecated("0.7",
"Use :func:`.expression.text` to create text constructs.")
def text(self, text, *args, **kwargs):
- """Return a :func:`~sqlalchemy.sql.expression.text` construct,
+ """Return a :func:`~sqlalchemy.sql.expression.text` construct,
bound to this engine.
This is equivalent to::
return expression.text(text, bind=self, *args, **kwargs)
- def _run_visitor(self, visitorcallable, element,
+ def _run_visitor(self, visitorcallable, element,
connection=None, **kwargs):
if connection is None:
conn = self.contextual_connect(close_with_result=False)
with a :class:`.Transaction` established.
E.g.::
-
+
with engine.begin() as conn:
conn.execute("insert into table (x, y, z) values (1, 2, 3)")
conn.execute("my_special_procedure(5)")
- Upon successful operation, the :class:`.Transaction`
+ Upon successful operation, the :class:`.Transaction`
is committed. If an error is raised, the :class:`.Transaction`
- is rolled back.
-
+ is rolled back.
+
The ``close_with_result`` flag is normally ``False``, and indicates
that the :class:`.Connection` will be closed when the operation
is complete. When set to ``True``, it indicates the :class:`.Connection`
has exhausted all result rows.
.. versionadded:: 0.7.6
-
+
See also:
-
+
:meth:`.Engine.connect` - procure a :class:`.Connection` from
an :class:`.Engine`.
"""Execute the given function within a transaction boundary.
The function is passed a :class:`.Connection` newly procured
- from :meth:`.Engine.contextual_connect` as the first argument,
+ from :meth:`.Engine.contextual_connect` as the first argument,
followed by the given \*args and \**kwargs.
-
+
e.g.::
-
+
def do_something(conn, x, y):
conn.execute("some statement", {'x':x, 'y':y})
engine.transaction(do_something, 5, 10)
-
+
The operations inside the function are all invoked within the
- context of a single :class:`.Transaction`.
- Upon success, the transaction is committed. If an
+ context of a single :class:`.Transaction`.
+ Upon success, the transaction is committed. If an
exception is raised, the transaction is rolled back
before propagating the exception.
The :meth:`.transaction` method is superseded by
the usage of the Python ``with:`` statement, which can
be used with :meth:`.Engine.begin`::
-
+
with engine.begin() as conn:
conn.execute("some statement", {'x':5, 'y':10})
-
+
See also:
-
- :meth:`.Engine.begin` - engine-level transactional
+
+ :meth:`.Engine.begin` - engine-level transactional
context
-
+
:meth:`.Connection.transaction` - connection-level version of
:meth:`.Engine.transaction`
The given \*args and \**kwargs are passed subsequent
to the :class:`.Connection` argument.
- This function, along with :meth:`.Connection.run_callable`,
+ This function, along with :meth:`.Connection.run_callable`,
allows a function to be run with a :class:`.Connection`
or :class:`.Engine` object without the need to know
which one is being dealt with.
"""
- return self._connection_cls(self,
- self.pool.connect(),
- close_with_result=close_with_result,
+ return self._connection_cls(self,
+ self.pool.connect(),
+ close_with_result=close_with_result,
**kwargs)
def table_names(self, schema=None, connection=None):
Uses the given :class:`.Connection`, or if None produces
its own :class:`.Connection`, and passes the ``table``
- and ``include_columns`` arguments onto that
+ and ``include_columns`` arguments onto that
:class:`.Connection` object's :meth:`.Connection.reflecttable`
method. The :class:`.Table` object is then populated
with new attributes.
def raw_connection(self):
"""Return a "raw" DBAPI connection from the connection pool.
- The returned object is a proxied version of the DBAPI
+ The returned object is a proxied version of the DBAPI
connection object used by the underlying driver in use.
The object will have all the same behavior as the real DBAPI
connection, except that its ``close()`` method will result in the
# __setstate__.
from sqlalchemy.cresultproxy import safe_rowproxy_reconstructor
- # The extra function embedding is needed so that the
- # reconstructor function has the same signature whether or not
+ # The extra function embedding is needed so that the
+ # reconstructor function has the same signature whether or not
# the extension is present.
def rowproxy_reconstructor(cls, state):
return safe_rowproxy_reconstructor(cls, state)
return iter(self)
try:
- # Register RowProxy with Sequence,
+ # Register RowProxy with Sequence,
# so sequence protocol is implemented
from collections import Sequence
Sequence.register(RowProxy)
primary_keymap[i] = rec
# populate primary keymap, looking for conflicts.
- if primary_keymap.setdefault(name.lower(), rec) is not rec:
+ if primary_keymap.setdefault(name.lower(), rec) is not rec:
# place a record that doesn't have the "index" - this
# is interpreted later as an AmbiguousColumnError,
- # but only when actually accessed. Columns
+ # but only when actually accessed. Columns
# colliding by name is not a problem if those names
# aren't used; integer and ColumnElement access is always
# unambiguous.
def _set_keymap_synonym(self, name, origname):
"""Set a synonym for the given name.
- Some dialects (SQLite at the moment) may use this to
+ Some dialects (SQLite at the moment) may use this to
adjust the column names that are significant within a
row.
result = map.get(key.lower())
# fallback for targeting a ColumnElement to a textual expression
# this is a rare use case which only occurs when matching text()
- # or colummn('name') constructs to ColumnElements, or after a
+ # or colummn('name') constructs to ColumnElements, or after a
# pickle/unpickle roundtrip
elif isinstance(key, expression.ColumnElement):
if key._label and key._label.lower() in map:
elif hasattr(key, 'name') and key.name.lower() in map:
# match is only on name.
result = map[key.name.lower()]
- # search extra hard to make sure this
+ # search extra hard to make sure this
# isn't a column/label name overlap.
# this check isn't currently available if the row
# was unpickled.
if result is None:
if raiseerr:
raise exc.NoSuchColumnError(
- "Could not locate column in row for column '%s'" %
+ "Could not locate column in row for column '%s'" %
expression._string_or_unprintable(key))
else:
return None
col3 = row[mytable.c.mycol] # access via Column object.
``ResultProxy`` also handles post-processing of result column
- data using ``TypeEngine`` objects, which are referenced from
+ data using ``TypeEngine`` objects, which are referenced from
the originating SQL statement that produced this result set.
"""
"""Return the 'rowcount' for this result.
The 'rowcount' reports the number of rows *matched*
- by the WHERE criterion of an UPDATE or DELETE statement.
-
+ by the WHERE criterion of an UPDATE or DELETE statement.
+
.. note::
-
+
Notes regarding :attr:`.ResultProxy.rowcount`:
-
-
+
+
* This attribute returns the number of rows *matched*,
which is not necessarily the same as the number of rows
that were actually *modified* - an UPDATE statement, for example,
may have no net change on a given row if the SET values
given are the same as those present in the row already.
Such a row would be matched but not modified.
- On backends that feature both styles, such as MySQL,
- rowcount is configured by default to return the match
+ On backends that feature both styles, such as MySQL,
+ rowcount is configured by default to return the match
count in all cases.
* :attr:`.ResultProxy.rowcount` is *only* useful in conjunction
with an UPDATE or DELETE statement. Contrary to what the Python
DBAPI says, it does *not* return the
number of rows available from the results of a SELECT statement
- as DBAPIs cannot support this functionality when rows are
+ as DBAPIs cannot support this functionality when rows are
unbuffered.
-
+
* :attr:`.ResultProxy.rowcount` may not be fully implemented by
all dialects. In particular, most DBAPIs do not support an
aggregate rowcount result from an executemany call.
- The :meth:`.ResultProxy.supports_sane_rowcount` and
+ The :meth:`.ResultProxy.supports_sane_rowcount` and
:meth:`.ResultProxy.supports_sane_multi_rowcount` methods
will report from the dialect if each usage is known to be
supported.
-
+
* Statements that use RETURNING may not return a correct
rowcount.
This is a DBAPI specific method and is only functional
for those backends which support it, for statements
- where it is appropriate. It's behavior is not
+ where it is appropriate. It's behavior is not
consistent across backends.
Usage of this method is normally unnecessary; the
return self._saved_cursor.lastrowid
except Exception, e:
self.connection._handle_dbapi_exception(
- e, None, None,
+ e, None, None,
self._saved_cursor, self.context)
raise
def returns_rows(self):
"""True if this :class:`.ResultProxy` returns rows.
- I.e. if it is legal to call the methods
- :meth:`~.ResultProxy.fetchone`,
+ I.e. if it is legal to call the methods
+ :meth:`~.ResultProxy.fetchone`,
:meth:`~.ResultProxy.fetchmany`
:meth:`~.ResultProxy.fetchall`.
@property
def is_insert(self):
"""True if this :class:`.ResultProxy` is the result
- of a executing an expression language compiled
+ of a executing an expression language compiled
:func:`.expression.insert` construct.
- When True, this implies that the
+ When True, this implies that the
:attr:`inserted_primary_key` attribute is accessible,
assuming the statement did not include
a user defined "returning" construct.
def inserted_primary_key(self):
"""Return the primary key for the row just inserted.
- The return value is a list of scalar values
+ The return value is a list of scalar values
corresponding to the list of primary key columns
in the target table.
- This only applies to single row :func:`.insert`
- constructs which did not explicitly specify
+ This only applies to single row :func:`.insert`
+ constructs which did not explicitly specify
:meth:`.Insert.returning`.
Note that primary key columns which specify a
- server_default clause,
+ server_default clause,
or otherwise do not qualify as "autoincrement"
columns (see the notes at :class:`.Column`), and were
generated using the database-side default, will
- appear in this list as ``None`` unless the backend
+ appear in this list as ``None`` unless the backend
supports "returning" and the insert statement executed
with the "implicit returning" enabled.
def supports_sane_rowcount(self):
"""Return ``supports_sane_rowcount`` from the dialect.
-
+
See :attr:`.ResultProxy.rowcount` for background.
-
+
"""
return self.dialect.supports_sane_rowcount
"""Return ``supports_sane_multi_rowcount`` from the dialect.
See :attr:`.ResultProxy.rowcount` for background.
-
+
"""
return self.dialect.supports_sane_multi_rowcount
return l
except Exception, e:
self.connection._handle_dbapi_exception(
- e, None, None,
+ e, None, None,
self.cursor, self.context)
raise
return l
except Exception, e:
self.connection._handle_dbapi_exception(
- e, None, None,
+ e, None, None,
self.cursor, self.context)
raise
return None
except Exception, e:
self.connection._handle_dbapi_exception(
- e, None, None,
+ e, None, None,
self.cursor, self.context)
raise
row = self._fetchone_impl()
except Exception, e:
self.connection._handle_dbapi_exception(
- e, None, None,
+ e, None, None,
self.cursor, self.context)
raise