Happy Friday all - SQLAlchemy 0.7.4 is released. This is the latest and greatest, the version of SQLAlchemy that I would choose above all others. Along with the recent release of the new migrations tool, Alembic, you guys should be all humming along very nicely with your databases at this point !
SQLAlchemy 0.7.4 has an unusually high number of new features and about thirty bugfixes. The most notable feature is that we finally added support for UPDATE..FROM. Other interesting features include a new Hybrid pattern, some new schema capabilities, and much better support for customized polymorphic_on schemes. There have also been lots and lots of documentation enhancements and improvements, as we continue to fully update every docstring to be up-to-date, accurate, and readable (there's many more to go, please bear with us !) SQLAlchemy 0.7.4 can be downloaded at: http://www.sqlalchemy.org/download.html Changlog to follow. 0.7.4 ===== - orm - [bug] Fixed backref behavior when "popping" the value off of a many-to-one in response to a removal from a stale one-to-many - the operation is skipped, since the many-to-one has since been updated. [ticket:2315] - [bug] After some years of not doing this, added more granularity to the "is X a parent of Y" functionality, which is used when determining if the FK on "Y" needs to be "nulled out" as well as if "Y" should be deleted with delete-orphan cascade. The test now takes into account the Python identity of the parent as well its identity key, to see if the last known parent of Y is definitely X. If a decision can't be made, a StaleDataError is raised. The conditions where this error is raised are fairly rare, requiring that the previous parent was garbage collected, and previously could very well inappropriately update/delete a record that's since moved onto a new parent, though there may be some cases where "silent success" occurred previously that will now raise in the face of ambiguity. Expiring "Y" resets the "parent" tracker, meaning X.remove(Y) could then end up deleting Y even if X is stale, but this is the same behavior as before; it's advised to expire X also in that case. [ticket:2264] - [bug] fixed inappropriate evaluation of user-mapped object in a boolean context within query.get() [ticket:2310]. Also in 0.6.9. - [bug] Added missing comma to PASSIVE_RETURN_NEVER_SET symbol [ticket:2304] - [bug] Cls.column.collate("some collation") now works. [ticket:1776] Also in 0.6.9 - [bug] the value of a composite attribute is now expired after an insert or update operation, instead of regenerated in place. This ensures that a column value which is expired within a flush will be loaded first, before the composite is regenerated using that value. [ticket:2309] - [bug] The fix in [ticket:2309] also emits the "refresh" event when the composite value is loaded on access, even if all column values were already present, as is appropriate. This fixes the "mutable" extension which relies upon the "load" event to ensure the _parents dictionary is up to date, fixes [ticket:2308]. Thanks to Scott Torborg for the test case here. - [bug] Fixed bug whereby a subclass of a subclass using concrete inheritance in conjunction with the new ConcreteBase or AbstractConcreteBase would fail to apply the subclasses deeper than one level to the "polymorphic loader" of each base [ticket:2312] - [bug] Fixed bug whereby a subclass of a subclass using the new AbstractConcreteBase would fail to acquire the correct "base_mapper" attribute when the "base" mapper was generated, thereby causing failures later on. [ticket:2312] - [bug] Fixed bug whereby column_property() created against ORM-level column could be treated as a distinct entity when producing certain kinds of joined-inh joins. [ticket:2316] - [bug] Fixed the error formatting raised when a tuple is inadvertently passed to session.query() [ticket:2297]. Also in 0.6.9. - [bug] Calls to query.join() to a single-table inheritance subclass are now tracked, and are used to eliminate the additional WHERE.. IN criterion normally tacked on with single table inheritance, since the join should accommodate it. This allows OUTER JOIN to a single table subclass to produce the correct results, and overall will produce fewer WHERE criterion when dealing with single table inheritance joins. [ticket:2328] - [bug] __table_args__ can now be passed as an empty tuple as well as an empty dict. [ticket:2339]. Thanks to Fayaz Yusuf Khan for the patch. - [bug] Updated warning message when setting delete-orphan without delete to no longer refer to 0.6, as we never got around to upgrading this to an exception. Ideally this might be better as an exception but it's not critical either way. [ticket:2325] - [feature] polymorphic_on now accepts many new kinds of values: - standalone expressions that aren't otherwise mapped - column_property() objects - string names of any column_property() or attribute name of a mapped Column The docs include an example using the case() construct, which is likely to be a common constructed used here. [ticket:2345] and part of [ticket:2238] Standalone expressions in polymorphic_on propagate to single-table inheritance subclasses so that they are used in the WHERE /JOIN clause to limit rows to that subclass as is the usual behavior. - [feature] IdentitySet supports the - operator as the same as difference(), handy when dealing with Session.dirty etc. [ticket:2301] - [feature] Added new value for Column autoincrement called "ignore_fk", can be used to force autoincrement on a column that's still part of a ForeignKeyConstraint. New example in the relationship docs illustrates its use. - [bug] Fixed bug in get_history() when referring to a composite attribute that has no value; added coverage for get_history() regarding composites which is otherwise just a userland function. - sql - [bug] related to [ticket:2316], made some adjustments to the change from [ticket:2261] regarding the "from" list on a select(). The _froms collection is no longer memoized, as this simplifies various use cases and removes the need for a "warning" if a column is attached to a table after it was already used in an expression - the select() construct will now always produce the correct expression. There's probably no real-world performance hit here; select() objects are almost always made ad-hoc, and systems that wish to optimize the re-use of a select() would be using the "compiled_cache" feature. A hit which would occur when calling select.bind has been reduced, but the vast majority of users shouldn't be using "bound metadata" anyway :). - [feature] The update() construct can now accommodate multiple tables in the WHERE clause, which will render an "UPDATE..FROM" construct, recognized by Postgresql and MSSQL. When compiled on MySQL, will instead generate "UPDATE t1, t2, ..". MySQL additionally can render against multiple tables in the SET clause, if Column objects are used as keys in the "values" parameter or generative method. [ticket:2166] [ticket:1944] - [feature] Added accessor to types called "python_type", returns the rudimentary Python type object for a particular TypeEngine instance, if known, else raises NotImplementedError. [ticket:77] - [bug] further tweak to the fix from [ticket:2261], so that generative methods work a bit better off of cloned (this is almost a non-use case though). In particular this allows with_only_columns() to behave more consistently. Added additional documentation to with_only_columns() to clarify expected behavior, which changed as a result of [ticket:2261]. [ticket:2319] - engine - [bug] Fixed bug whereby transaction.rollback() would throw an error on an invalidated connection if the transaction were a two-phase or savepoint transaction. For plain transactions, rollback() is a no-op if the connection is invalidated, so while it wasn't 100% clear if it should be a no-op, at least now the interface is consistent. [ticket:2317] - schema - [feature] Added new support for remote "schemas": - MetaData() accepts "schema" and "quote_schema" arguments, which will be applied to the same-named arguments of a Table or Sequence which leaves these at their default of ``None``. - Sequence accepts "quote_schema" argument - tometadata() for Table will use the "schema" of the incoming MetaData for the new Table if the schema argument is explicitly "None" - Added CreateSchema and DropSchema DDL constructs - these accept just the string name of a schema and a "quote" flag. - When using default "schema" with MetaData, ForeignKey will also assume the "default" schema when locating remote table. This allows the "schema" argument on MetaData to be applied to any set of Table objects that otherwise don't have a "schema". - a "has_schema" method has been implemented on dialect, but only works on Postgresql so far. Courtesy Manlio Perillo, [ticket:1679] - [feature] The "extend_existing" flag on Table now allows for the reflection process to take effect for a Table object that's already been defined; when autoload=True and extend_existing=True are both set, the full set of columns will be reflected from the Table which will then *overwrite* those columns already present, rather than no activity occurring. Columns that are present directly in the autoload run will be used as always, however. [ticket:1410] - [bug] Fixed bug whereby TypeDecorator would return a stale value for _type_affinity, when using a TypeDecorator that "switches" types, like the CHAR/UUID type. - [bug] Fixed bug whereby "order_by='foreign_key'" option to Inspector.get_table_names wasn't implementing the sort properly, replaced with the existing sort algorithm - [bug] the "name" of a column-level CHECK constraint, if present, is now rendered in the CREATE TABLE statement using "CONSTRAINT <name> CHECK <expression>". [ticket:2305] - pyodbc - [bug] pyodbc-based dialects now parse the pyodbc accurately as far as observed pyodbc strings, including such gems as "py3-3.0.1-beta4" [ticket:2318] - postgresql - [bug] Postgresql dialect memoizes that an ENUM of a particular name was processed during a create/drop sequence. This allows a create/drop sequence to work without any calls to "checkfirst", and also means with "checkfirst" turned on it only needs to check for the ENUM once. [ticket:2311] - [feature] Added create_type constructor argument to pg.ENUM. When False, no CREATE/DROP or checking for the type will be performed as part of a table create/drop event; only the create()/drop)() methods called directly will do this. Helps with Alembic "offline" scripts. - mssql - [feature] lifted the restriction on SAVEPOINT for SQL Server. All tests pass using it, it's not known if there are deeper issues however. [ticket:822] - [bug] repaired the with_hint() feature which wasn't implemented correctly on MSSQL - usually used for the "WITH (NOLOCK)" hint (which you shouldn't be using anyway ! use snapshot isolation instead :) ) [ticket:2336] - [bug] use new pyodbc version detection for _need_decimal_fix option, [ticket:2318] - [bug] don't cast "table name" as NVARCHAR on SQL Server 2000. Still mostly in the dark what incantations are needed to make PyODBC work fully with FreeTDS 0.91 here, however. [ticket:2343] - [bug] Decode incoming values when retrieving list of index names and the names of columns within those indexes. [ticket:2269] - mysql - [bug] Unicode adjustments allow latest pymysql (post 0.4) to pass 100% on Python 2. - ext - [feature] Added an example to the hybrid docs of a "transformer" - a hybrid that returns a query-transforming callable in combination with a custom comparator. Uses a new method on Query called with_transformation(). The use case here is fairly experimental, but only adds one line of code to Query. - [bug] the @compiles decorator raises an informative error message when no "default" compilation handler is present, rather than KeyError. - examples - [bug] Fixed bug in history_meta.py example where the "unique" flag was not removed from a single-table-inheritance subclass which generates columns to put up onto the base. -- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To post to this group, send email to sqlalchemy@googlegroups.com. To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en.