Greetings -

SQLAlchemy 0.6.5 is released.     As we approach towards the start of 0.7, 
where a good stack of branches are accumulating, the 0.6 series starts to come 
in for a landing.  0.6 has been tremendously successful, with 0.6.4 logging 
28,143 downloads from Pypi alone over a period of 7 weeks.   I've rolled out 
the 0.6 series on two different very different projects - one a sprawling, 
rapidly developed social media platform, the other a formal and constrained 
financial analysis application.  Both exercise the ORM and Core to a very deep 
degree in a broad range of situations - within web applications which make 
heavy usage of the Beaker caching system and various forms of eager loading, 
within backend services that run many concurrent operations and transactions 
via multiprocessing, in bulk loader scripts which efficiently flush through 
tens of thousands of interconnected objects, in expressions that make great 
usage of dates, intervals, decimals, custom types, generic transformations and 
subqueries, in models constructed around joined and single table inheritance, 
update and delete cascades, lots of transparent versioning.  So I'm pretty 
happy with it, and I hope most people out there are as well.

0.6.5 has the usual longer than expected list of changes, a bunch of new 
features, fixes for many mostly relatively minor bugs.

Download SQLAlchemy 0.6.5 at :

http://www.sqlalchemy.org/download.html

0.6.5
=====
- orm
  - Added a new "lazyload" option "immediateload".  
    Issues the usual "lazy" load operation automatically
    as the object is populated.   The use case
    here is when loading objects to be placed in
    an offline cache, or otherwise used after
    the session isn't available, and straight 'select'
    loading, not 'joined' or 'subquery', is desired.
    [ticket:1914]
  
  - New Query methods: query.label(name), query.as_scalar(),
    return the query's statement as a scalar subquery
    with /without label [ticket:1920];
    query.with_entities(*ent), replaces the SELECT list of 
    the query with new entities. 
    Roughly equivalent to a generative form of query.values()
    which accepts mapped entities as well as column 
    expressions.
    
  - Fixed recursion bug which could occur when moving
    an object from one reference to another, with 
    backrefs involved, where the initiating parent
    was a subclass (with its own mapper) of the 
    previous parent.

  - Fixed a regression in 0.6.4 which occurred if you 
    passed an empty list to "include_properties" on 
    mapper() [ticket:1918]
  
  - Fixed labeling bug in Query whereby the NamedTuple
    would mis-apply labels if any of the column
    expressions were un-labeled.
    
  - Patched a case where query.join() would adapt the
    right side to the right side of the left's join
    inappropriately [ticket:1925]

  - Query.select_from() has been beefed up to help
    ensure that a subsequent call to query.join()
    will use the select_from() entity, assuming it's
    a mapped entity and not a plain selectable, 
    as the default "left" side, not the first entity 
    in the Query object's list of entities.
    
  - The exception raised by Session when it is used
    subsequent to a subtransaction rollback (which is what
    happens when a flush fails in autocommit=False mode) has
    now been reworded (this is the "inactive due to a
    rollback in a subtransaction" message). In particular,
    if the rollback was due to an exception during flush(),
    the message states this is the case, and reiterates the
    string form of the original exception that occurred
    during flush. If the session is closed due to explicit
    usage of subtransactions (not very common), the message
    just states this is the case.

  - The exception raised by Mapper when repeated requests to
    its initialization are made after initialization already
    failed no longer assumes the "hasattr" case, since
    there's other scenarios in which this message gets
    emitted, and the message also does not compound onto
    itself multiple times - you get the same message for
    each attempt at usage. The misnomer "compiles" is being
    traded out for "initialize".

  - Fixed bug in query.update() where 'evaluate' or 'fetch'
    expiration would fail if the column expression key was
    a class attribute with a different keyname as the 
    actual column name.  [ticket:1935]
    
  - Added an assertion during flush which ensures
    that no NULL-holding identity keys were generated
    on "newly persistent" objects.
    This can occur when user defined code inadvertently
    triggers flushes on not-fully-loaded objects.

  - lazy loads for relationship attributes now use
    the current state, not the "committed" state,
    of foreign and primary key attributes
    when issuing SQL, if a flush is not in process.
    Previously, only the database-committed state would 
    be used.  In particular, this would cause a many-to-one
    get()-on-lazyload operation to fail, as autoflush
    is not triggered on these loads when the attributes are
    determined and the "committed" state may not be 
    available.  [ticket:1910]
    
  - A new flag on relationship(), load_on_pending, allows
    the lazy loader to fire off on pending objects without a
    flush taking place, as well as a transient object that's
    been manually "attached" to the session. Note that this
    flag blocks attribute events from taking place when an
    object is loaded, so backrefs aren't available until
    after a flush. The flag is only intended for very
    specific use cases.
  
  - Another new flag on relationship(), cascade_backrefs,
    disables the "save-update" cascade when the event was
    initiated on the "reverse" side of a bidirectional 
    relationship.   This is a cleaner behavior so that
    many-to-ones can be set on a transient object without
    it getting sucked into the child object's session,
    while still allowing the forward collection to 
    cascade.   We *might* default this to False in 0.7.
      
  - Slight improvement to the behavior of
    "passive_updates=False" when placed only on the
    many-to-one side of a relationship; documentation has
    been clarified that passive_updates=False should really
    be on the one-to-many side.

  - Placing passive_deletes=True on a many-to-one emits
    a warning, since you probably intended to put it on
    the one-to-many side.
  
  - Fixed bug that would prevent "subqueryload" from
    working correctly with single table inheritance 
    for a relationship from a subclass - the "where 
    type in (x, y, z)" only gets placed on the inside,
    instead of repeatedly.
    
  - When using from_self() with single table inheritance,
    the "where type in (x, y, z)" is placed on the outside
    of the query only, instead of repeatedly.   May make
    some more adjustments to this.

  - scoped_session emits a warning when configure() is 
    called if a Session is already present (checks only the
    current thread) [ticket:1924]

  - reworked the internals of mapper.cascade_iterator() to
    cut down method calls by about 9% in some circumstances.
    [ticket:1932]
    
- sql
   - Fixed bug in TypeDecorator whereby the dialect-specific
     type was getting pulled in to generate the DDL for a 
     given type, which didn't always return the correct result.
     
   - TypeDecorator can now have a fully constructed type
     specified as its "impl", in addition to a type class.

   - TypeDecorator will now place itself as the resulting
     type for a binary expression where the type coercion
     rules would normally return its impl type - previously,
     a copy of the impl type would be returned which would
     have the TypeDecorator embedded into it as the "dialect"
     impl, this was probably an unintentional way of achieving
     the desired effect.

   - TypeDecorator.load_dialect_impl() returns "self.impl" by
     default, i.e. not the dialect implementation type of 
     "self.impl".   This to support compilation correctly.  
     Behavior can be user-overridden in exactly the same way 
     as before to the same effect.

   - Added type_coerce(expr, type_) expression element.  
     Treats the given expression as the given type when evaluating
     expressions and processing result rows, but does not 
     affect the generation of SQL, other than an anonymous
     label.
     
   - Table.tometadata() now copies Index objects associated
     with the Table as well.

   - Table.tometadata() issues a warning if the given Table 
     is already present in the target MetaData - the existing
     Table object is returned.

   - An informative error message is raised if a Column 
     which has not yet been assigned a name, i.e. as in 
     declarative, is used in a context where it is
     exported to the columns collection of an enclosing
     select() construct, or if any construct involving
     that column is compiled before its name is 
     assigned.

   - as_scalar(), label() can be called on a selectable
     which contains a Column that is not yet named.
     [ticket:1862]

   - Fixed recursion overflow which could occur when operating
     with two expressions both of type "NullType", but
     not the singleton NULLTYPE instance. [ticket:1907]
     
- declarative
   - @classproperty (soon/now @declared_attr) takes effect for 
     __mapper_args__, __table_args__, __tablename__ on 
     a base class that is not a mixin, as well as mixins.
     [ticket:1922]

   - @classproperty 's official name/location for usage
     with declarative is sqlalchemy.ext.declarative.declared_attr.
     Same thing, but moving there since it is more of a
     "marker" that's specific to declararative, 
     not just an attribute technique.  [ticket:1915]

   - Fixed bug whereby columns on a mixin wouldn't propagate
     correctly to a single-table, or joined-table,
     inheritance scheme where the attribute name is
     different than that of the column. [ticket:1930],
     [ticket:1931].

   - A mixin can now specify a column that overrides 
     a column of the same name associated with a superclass.
     Thanks to Oystein Haaland.
     
- engine
   
   - Fixed a regression in 0.6.4 whereby the change that
     allowed cursor errors to be raised consistently broke
     the result.lastrowid accessor.   Test coverage has
     been added for result.lastrowid.   Note that lastrowid
     is only supported by Pysqlite and some MySQL drivers,
     so isn't super-useful in the general case.
   
   - the logging message emitted by the engine when
     a connection is first used is now "BEGIN (implicit)" 
     to emphasize that DBAPI has no explicit begin().
   
   - added "views=True" option to metadata.reflect(), 
     will add the list of available views to those
     being reflected.  [ticket:1936]

   - engine_from_config() now accepts 'debug' for 
     'echo', 'echo_pool', 'force' for 'convert_unicode',
     boolean values for 'use_native_unicode'.  
     [ticket:1899]

- postgresql
   - Added "as_tuple" flag to ARRAY type, returns results
     as tuples instead of lists to allow hashing.

   - Fixed bug which prevented "domain" built from a 
     custom type such as "enum" from being reflected.
     [ticket:1933]

- mysql
   - Fixed bug involving reflection of CURRENT_TIMESTAMP 
     default used with ON UPDATE clause, thanks to 
     Taavi Burns [ticket:1940]

- oracle
   - The implicit_retunring argument to create_engine()
     is now honored regardless of detected version of 
     Oracle.  Previously, the flag would be forced
     to False if server version info was < 10.
     [ticket:1878]
     
- mssql
   - Fixed reflection bug which did not properly handle
     reflection of unknown types.  [ticket:1946]
    
   - Fixed bug where aliasing of tables with "schema" would
     fail to compile properly.  [ticket:1943]

   - Rewrote the reflection of indexes to use sys. 
     catalogs, so that column names of any configuration
     (spaces, embedded commas, etc.) can be reflected.
     Note that reflection of indexes requires SQL 
     Server 2005 or greater.  [ticket:1770]
     
   - mssql+pymssql dialect now honors the "port" portion
     of the URL instead of discarding it.  [ticket:1952]
     
- informix
   - *Major* cleanup / modernization of the Informix 
     dialect for 0.6, courtesy Florian Apolloner. 
     [ticket:1906]

- tests
   - the NoseSQLAlchemyPlugin has been moved to a
     new package "sqlalchemy_nose" which installs
     along with "sqlalchemy".  This so that the "nosetests"
     script works as always but also allows the 
     --with-coverage option to turn on coverage before
     SQLAlchemy modules are imported, allowing coverage
     to work correctly.
      
- misc
   - CircularDependencyError now has .cycles and .edges
     members, which are the set of elements involved in
     one or more cycles, and the set of edges as 2-tuples.  
     [ticket:1890]

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalch...@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.

Reply via email to