The first official 0.6 release of SQLAlchemy is now available.    

0.6 includes a newly rewritten unit of work implementation originally slated 
for 0.7, but then as it went so well we decided on 0.6.1, and then because it 
continued to perform terrifically within several punishing environments we 
decided to go with 0.6.0.   I'm very excited to have 0.6.0 out with the clean 
UOW system, as the old one was pretty much the last vestige of an earlier era 
for SQLAlchemy.   As we come up on our 5th birthday, SQLAlchemy has grown and 
matured to a dramatic degree, thanks in large part to the very generous and 
supportive community who have pushed us to produce an ever more awesome product.

I hope everyone enjoys this release and don't hesitate to report any bugs on 
the wiki.  Thanks for sticking around.

Changes for 0.6 below are relative to 0.6beta3.   For a full overview of what 
0.6 is about, see the "What's New?" document at 
http://www.sqlalchemy.org/trac/wiki/06Migration .

Download SQLAlchemy 0.6.0 at:

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

0.6.0
=====

- orm
  - Unit of work internals have been rewritten.  Units of work
    with large numbers of objects interdependent objects 
    can now be flushed without recursion overflows 
    as there is no longer reliance upon recursive calls
    [ticket:1081].  The number of internal structures now stays 
    constant for a particular session state, regardless of 
    how many relationships are present on mappings.  The flow 
    of events now corresponds to a linear list of steps, 
    generated by the mappers and relationships based on actual
    work to be done, filtered through a single topological sort 
    for correct ordering.  Flush actions are assembled using 
    far fewer steps and less memory. [ticket:1742]

  - Along with the UOW rewrite, this also removes an issue
    introduced in 0.6beta3 regarding topological cycle detection 
    for units of work with long dependency cycles.  We now use
    an algorithm written by Guido (thanks Guido!).

  - one-to-many relationships now maintain a list of positive
    parent-child associations within the flush, preventing
    previous parents marked as deleted from cascading a 
    delete or NULL foreign key set on those child objects,
    despite the end-user not removing the child from the old
    association. [ticket:1764]

  - A collection lazy load will switch off default 
    eagerloading on the reverse many-to-one side, since 
    that loading is by definition unnecessary.  [ticket:1495]

  - Session.refresh() now does an equivalent expire()
    on the given instance first, so that the "refresh-expire"
    cascade is propagated.   Previously, refresh() was
    not affected in any way by the presence of "refresh-expire"
    cascade.   This is a change in behavior versus that
    of 0.6beta2, where the "lockmode" flag passed to refresh()
    would cause a version check to occur.  Since the instance
    is first expired, refresh() always upgrades the object
    to the most recent version.
    
  - The 'refresh-expire' cascade, when reaching a pending object,
    will expunge the object if the cascade also includes
    "delete-orphan", or will simply detach it otherwise.
    [ticket:1754]

  - id(obj) is no longer used internally within topological.py,
    as the sorting functions now require hashable objects
    only.  [ticket:1756]

  - The ORM will set the docstring of all generated descriptors
    to None by default.  This can be overridden using 'doc'
    (or if using Sphinx, attribute docstrings work too).
    
  - Added kw argument 'doc' to all mapper property callables 
    as well as Column().  Will assemble the string 'doc' as 
    the '__doc__' attribute on the descriptor.  

  - Usage of version_id_col on a backend that supports 
    cursor.rowcount for execute() but not executemany() now works
    when a delete is issued (already worked for saves, since those
    don't use executemany()). For a backend that doesn't support 
    cursor.rowcount at all, a warning is emitted the same
    as with saves.  [ticket:1761]

  - The ORM now short-term caches the "compiled" form of
    insert() and update() constructs when flushing lists of 
    objects of all the same class, thereby avoiding redundant
    compilation per individual INSERT/UPDATE within an 
    individual flush() call.
    
  - internal getattr(), setattr(), getcommitted() methods
    on ColumnProperty, CompositeProperty, RelationshipProperty
    have been underscored (i.e. are private), signature has 
    changed.
    
- engines
  - The C extension now also works with DBAPIs which use custom
    sequences as row (and not only tuples). [ticket:1757]

- sql
  - Restored some bind-labeling logic from 0.5 which ensures
    that tables with column names that overlap another column
    of the form "<tablename>_<columnname>" won't produce 
    errors if column._label is used as a bind name during
    an UPDATE.  Test coverage which wasn't present in 0.5
    has been added.  [ticket:1755]

  - somejoin.select(fold_equivalents=True) is no longer 
    deprecated, and will eventually be rolled into a more 
    comprehensive version of the feature for [ticket:1729].
    
  - the Numeric type raises an *enormous* warning when expected
    to convert floats to Decimal from a DBAPI that returns floats.
    This includes SQLite, Sybase, MS-SQL. [ticket:1759]

  - Fixed an error in expression typing which caused an endless
    loop for expressions with two NULL types.
  
  - Fixed bug in execution_options() feature whereby the existing
    Transaction and other state information from the parent 
    connection would not be propagated to the sub-connection.

  - Added new 'compiled_cache' execution option.  A dictionary 
    where Compiled objects will be cached when the Connection
    compiles a clause expression into a dialect- and parameter- 
    specific Compiled object.  It is the user's responsibility to
    manage the size of this dictionary, which will have keys
    corresponding to the dialect, clause element, the column
    names within the VALUES or SET clause of an INSERT or UPDATE, 
    as well as the "batch" mode for an INSERT or UPDATE statement.
  
  - Added get_pk_constraint() to reflection.Inspector, similar
    to get_primary_keys() except returns a dict that includes the
    name of the constraint, for supported backends (PG so far).
    [ticket:1769]

  - Table.create() and Table.drop() no longer apply metadata-
    level create/drop events.  [ticket:1771]
    
- ext
  - the compiler extension now allows @compiles decorators
    on base classes that extend to child classes, @compiles
    decorators on child classes that aren't broken by a 
    @compiles decorator on the base class.
   
  - Declarative will raise an informative error message
    if a non-mapped class attribute is referenced in the
    string-based relationship() arguments.

  - Further reworked the "mixin" logic in declarative to 
    additionally allow __mapper_args__ as a @classproperty
    on a mixin, such as to dynamically assign polymorphic_identity.

- postgresql
  - Postgresql now reflects sequence names associated with 
    SERIAL columns correctly, after the name of of the sequence
    has been changed.  Thanks to Kumar McMillan for the patch.
    [ticket:1071]
    
  - Repaired missing import in psycopg2._PGNumeric type when 
    unknown numeric is received.

  - psycopg2/pg8000 dialects now aware of REAL[], FLOAT[], 
    DOUBLE_PRECISION[], NUMERIC[] return types without
    raising an exception.

  - Postgresql reflects the name of primary key constraints,
    if one exists.  [ticket:1769]
        
- oracle
  - Now using cx_oracle output converters so that the
    DBAPI returns natively the kinds of values we prefer:
    - NUMBER values with positive precision + scale convert
      to cx_oracle.STRING and then to Decimal.   This 
      allows perfect precision for the Numeric type when
      using cx_oracle.  [ticket:1759]
    - STRING/FIXED_CHAR now convert to unicode natively.
      SQLAlchemy's String types then don't need to 
      apply any kind of conversions.

- firebird
   - The functionality of result.rowcount can be disabled on a
     per-engine basis by setting 'enable_rowcount=False' 
     on create_engine().  Normally, cursor.rowcount is called
     after any UPDATE or DELETE statement unconditionally,
     because the cursor is then closed and Firebird requires
     an open cursor in order to get a rowcount.  This 
     call is slightly expensive however so it can be disabled.
     To re-enable on a per-execution basis, the 
     'enable_rowcount=True' execution option may be used.
     
- examples
  - Updated attribute_shard.py example to use a more robust
    method of searching a Query for binary expressions which
    compare columns against literal values.
    



-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.

Reply via email to