SQLAlchemy 0.6.4 is now available, with a significantly large number of 
enhancements and fixes.

A large focus of this release is on clarification and ease of use, including:

- the largest documentation reorganization since we moved to Sphinx, with an 
emphasis on 
one-location-per-concept.  no more jumping around to the "API Reference" to 
find things.

- revamp of the error messages when dealing with primaryjoin issues, more 
forgiving behavior
when it's clear what the user intent was

- more warnings for known configurational mistakes with the ORM

Other changes include:

- an up to 90% call reduction within mapper.py when flushing highly polymorphic 
structures

- Fixed psycopg2 isolation mode setting

- lots of ORM / SQL / engine fixes

I am always amazed at how fast CHANGES grows from the previous release, only 
around 6 weeks ago.    

Download SQLAlchemy 0.6.4 at:

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

0.6.4
=====
- orm
  - The name ConcurrentModificationError has been
    changed to StaleDataError, and descriptive 
    error messages have been revised to reflect
    exactly what the issue is.   Both names will
    remain available for the forseeable future
    for schemes that may be specifying 
    ConcurrentModificationError in an "except:"
    clause.

  - Added a mutex to the identity map which mutexes
    remove operations against iteration methods,
    which now pre-buffer before returning an 
    iterable.   This because asyncrhonous gc 
    can remove items via the gc thread at any time.
    [ticket:1891]
    
  - The Session class is now present in sqlalchemy.orm.*.
    We're moving away from the usage of create_session(),
    which has non-standard defaults, for those situations
    where a one-step Session constructor is desired. Most
    users should stick with sessionmaker() for general use,
    however.
  
  - query.with_parent() now accepts transient objects
    and will use the non-persistent values of their pk/fk
    attributes in order to formulate the criterion.  
    Docs are also clarified as to the purpose of with_parent().
    
  - The include_properties and exclude_properties arguments
    to mapper() now accept Column objects as members in 
    addition to strings.  This so that same-named Column
    objects, such as those within a join(), can be
    disambiguated.

  - A warning is now emitted if a mapper is created against a
    join or other single selectable that includes multiple
    columns with the same name in its .c. collection,
    and those columns aren't explictly named as part of
    the same or separate attributes (or excluded).
    In 0.7 this warning will be an exception.   Note that
    this warning is not emitted when the combination occurs
    as a result of inheritance, so that attributes
    still allow being overridden naturally.  
    [ticket:1896].  In 0.7 this will be improved further.
    
  - The primary_key argument to mapper() can now specify
    a series of columns that are only a subset of 
    the calculated "primary key" columns of the mapped 
    selectable, without an error being raised.  This
    helps for situations where a selectable's effective
    primary key is simpler than the number of columns
    in the selectable that are actually marked as 
    "primary_key", such as a join against two 
    tables on their primary key columns [ticket:1896].
    
  - An object that's been deleted now gets a flag
    'deleted', which prohibits the object from
    being re-add()ed to the session, as previously
    the object would live in the identity map
    silently until its attributes were accessed.
    The make_transient() function now resets this
    flag along with the "key" flag.

  - make_transient() can be safely called on an
    already transient instance.
    
  - a warning is emitted in mapper() if the polymorphic_on
    column is not present either in direct or derived
    form in the mapped selectable or in the 
    with_polymorphic selectable, instead of silently
    ignoring it.  Look for this to become an
    exception in 0.7.

  - Another pass through the series of error messages
    emitted when relationship() is configured with
    ambiguous arguments.   The "foreign_keys" 
    setting is no longer mentioned, as it is almost
    never needed and it is preferable users set up
    correct ForeignKey metadata, which is now the
    recommendation.  If 'foreign_keys'
    is used and is incorrect, the message suggests
    the attribute is probably unnecessary.  Docs
    for the attribute are beefed up.  This 
    because all confused relationship() users on the 
    ML appear to be attempting to use foreign_keys
    due to the message, which only confuses them
    further since Table metadata is much clearer.

  - If the "secondary" table has no ForeignKey metadata
    and no foreign_keys is set, even though the
    user is passing screwed up information, it is assumed
    that primary/secondaryjoin expressions should
    consider only and all cols in "secondary" to be 
    foreign.  It's not possible with "secondary" for 
    the foreign keys to be elsewhere in any case.
    A warning is now emitted instead of an error, 
    and the mapping succeeds. [ticket:1877]
    
  - Moving an o2m object from one collection to
    another, or vice versa changing the referenced
    object by an m2o, where the foreign key is also a
    member of the primary key, will now be more
    carefully checked during flush if the change in
    value of the foreign key on the "many" side is the
    result of a change in the primary key of the "one"
    side, or if the "one" is just a different object.
    In one case, a cascade-capable DB would have
    cascaded the value already and we need to look at
    the "new" PK value to do an UPDATE, in the other we
    need to continue looking at the "old". We now look
    at the "old", assuming passive_updates=True,
    unless we know it was a PK switch that
    triggered the change. [ticket:1856]
    
  - The value of version_id_col can be changed 
    manually, and this will result in an UPDATE
    of the row.  Versioned UPDATEs and DELETEs
    now use the "committed" value of the 
    version_id_col in the WHERE clause and
    not the pending changed value. The 
    version generator is also bypassed if 
    manual changes are present on the attribute.
    [ticket:1857]

  - Repaired the usage of merge() when used with 
    concrete inheriting mappers.  Such mappers frequently
    have so-called "concrete" attributes, which are
    subclass attributes that "disable" propagation from
    the parent - these needed to allow a merge()
    operation to pass through without effect.

  - Specifying a non-column based argument
    for column_mapped_collection, including string,
    text() etc., will raise an error message that
    specifically asks for a column element, no longer
    misleads with incorrect information about
    text() or literal().  [ticket:1863]

  - Similarly, for relationship(), foreign_keys,
    remote_side, order_by - all column-based 
    expressions are enforced - lists of strings
    are explicitly disallowed since this is a
    very common error
    
  - Dynamic attributes don't support collection 
    population - added an assertion for when
    set_committed_value() is called, as well as
    when joinedload() or subqueryload() options
    are applied to a dynamic attribute, instead
    of failure / silent failure.  [ticket:1864]

  - Fixed bug whereby generating a Query derived
    from one which had the same column repeated
    with different label names, typically 
    in some UNION situations, would fail to 
    propagate the inner columns completely to
    the outer query.  [ticket:1852]

  - object_session() raises the proper 
    UnmappedInstanceError when presented with an
    unmapped instance.  [ticket:1881]

  - Applied further memoizations to calculated Mapper
    properties, with significant (~90%) runtime mapper.py
    call count reduction in heavily polymorphic mapping
    configurations.

  - mapper _get_col_to_prop private method used 
    by the versioning example is deprecated; 
    now use mapper.get_property_by_column() which 
    will remain the public method for this.

  - the versioning example works correctly now
    if versioning on a col that was formerly 
    NULL.
    
- sql
  - Calling execute() on an alias() construct is pending
    deprecation for 0.7, as it is not itself an
    "executable" construct. It currently "proxies" its
    inner element and is conditionally "executable" but
    this is not the kind of ambiguity we like these days.
    
  - The execute() and scalar() methods of ClauseElement
    are now moved appropriately to the Executable
    subclass. ClauseElement.execute()/ scalar() are still
    present and are pending deprecation in 0.7, but note
    these would always raise an error anyway if you were
    not an Executable (unless you were an alias(), see
    previous note).
    
  - Added basic math expression coercion for 
    Numeric->Integer,
    so that resulting type is Numeric regardless
    of the direction of the expression.
    
  - Changed the scheme used to generate truncated
    "auto" index names when using the "index=True"
    flag on Column.   The truncation only takes
    place with the auto-generated name, not one
    that is user-defined (an error would be 
    raised instead), and the truncation scheme 
    itself is now based on a fragment of an md5
    hash of the identifier name, so that multiple
    indexes on columns with similar names still
    have unique names.  [ticket:1855]

  - The generated index name also is based on 
    a "max index name length" attribute which is
    separate from the "max identifier length" - 
    this to appease MySQL who has a max length
    of 64 for index names, separate from their
    overall max length of 255.  [ticket:1412]

  - the text() construct, if placed in a column
    oriented situation, will at least return NULLTYPE
    for its type instead of None, allowing it to 
    be used a little more freely for ad-hoc column
    expressions than before.   literal_column()
    is still the better choice, however.

  - Added full description of parent table/column, 
    target table/column in error message raised when
    ForeignKey can't resolve target.

  - Fixed bug whereby replacing composite foreign key
    columns in a reflected table would cause an attempt
    to remove the reflected constraint from the table
    a second time, raising a KeyError.  [ticket:1865]

  - the _Label construct, i.e. the one that is produced
    whenever you say somecol.label(), now counts itself
    in its "proxy_set" unioned with that of it's
    contained column's proxy set, instead of 
    directly returning that of the contained column.
    This allows column correspondence
    operations which depend on the identity of the 
    _Labels themselves to return the correct result
    - fixes ORM bug [ticket:1852].

- engine

  - Calling fetchone() or similar on a result that
    has already been exhausted, has been closed,
    or is not a result-returning result now 
    raises ResourceClosedError, a subclass of
    InvalidRequestError, in all cases, regardless
    of backend.  Previously, some DBAPIs would
    raise ProgrammingError (i.e. pysqlite), others
    would return None leading to downstream breakages
    (i.e. MySQL-python).

  - Fixed bug in Connection whereby if a "disconnect"
    event occurred in the "initialize" phase of the
    first connection pool connect, an AttributeError
    would be raised when the Connection would attempt
    to invalidate the DBAPI connection.  [ticket:1894]

  - Connection, ResultProxy, as well as Session use
    ResourceClosedError for all "this
    connection/transaction/result is closed" types of
    errors.

  - Connection.invalidate() can be called more than
    once and subsequent calls do nothing.

- declarative
  - if @classproperty is used with a regular class-bound
    mapper property attribute, it will be called to get the
    actual attribute value during initialization. Currently,
    there's no advantage to using @classproperty on a column
    or relationship attribute of a declarative class that
    isn't a mixin - evaluation is at the same time as if
    @classproperty weren't used. But here we at least allow
    it to function as expected.

  - Fixed bug where "Can't add additional column" message
    would display the wrong name.

- postgresql
  - Fixed the psycopg2 dialect to use its
    set_isolation_level() method instead of relying
    upon the base "SET SESSION ISOLATION" command,
    as psycopg2 resets the isolation level on each new 
    transaction otherwise.
    
- mssql
  - Fixed "default schema" query to work with
    pymssql backend.

- firebird
  - Fixed bug whereby a column default would fail to 
    reflect if the "default" keyword were lower case.
    
- oracle
  - Added ROWID type to the Oracle dialect, for those
    cases where an explicit CAST might be needed.
    [ticket:1879]

  - Oracle reflection of indexes has been tuned so
    that indexes which include some or all primary
    key columns, but not the same set of columns
    as that of the primary key, are reflected.
    Indexes which contain the identical columns
    as that of the primary key are skipped within
    reflection, as the index in that case is assumed
    to be the auto-generated primary key index.
    Previously, any index with PK columns present
    would be skipped.  Thanks to Kent Bower
    for the patch.  [ticket:1867]

  - Oracle now reflects the names of primary key
    constraints - also thanks to Kent Bower.
    [ticket:1868]

- informix
  - Applied patches from [ticket:1904] to get
    basic Informix functionality up again.  We
    rely upon end-user testing to ensure that
    Informix is working to some degree.

- documentation
  - The docs have been reorganized such that the "API
    Reference" section is gone - all the docstrings from
    there which were public API are moved into the
    context of the main doc section that talks about it.
    Main docs divided into "SQLAlchemy Core" and
    "SQLAlchemy ORM" sections, mapper/relationship docs
    have been broken out. Lots of sections rewritten
    and/or reorganized.
    
- examples
  - The beaker_caching example has been reorgnized
    such that the Session, cache manager, 
    declarative_base are part of environment, and
    custom cache code is portable and now within
    "caching_query.py".  This allows the example to 
    be easier to "drop in" to existing projects.

  - the history_meta versioning recipe sets "unique=False"
    when copying columns, so that the versioning 
    table handles multiple rows with repeating values.
    [ticket:1887]

-- 
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