I'd just like to echo Martin's statement, thank you very much. Just your responses to this list seem like a full time job, let alone the development to SQLAlchemy - which continues to surprise and impress me with it's features and support.

James.

On 08/02/2011 09:28 AM, Martijn Moeling wrote:
Thank you for all the effort you put in.
SQLAlchemy has been a proven tool for me and as it seems for many others.




On Aug 1, 2011, at 02:17 , Michael Bayer wrote:

SQLAlchemy version 0.7.2 is now available.

A lot has been going on leading up to this release, and there was actually a 
bunch more I've wanted to do;  but as we went about six weeks since the last 
release we've accumulated at least twenty five bug fixes, and it's time for 
them to go out.    Work continues towards the next release.

This release features a relatively big change to the mechanics of joined and subquery 
eager loading, which is that when invoked from a Query (as opposed to from a lazy load), 
the eager loader will traverse the graph of objects fully regardless of collections and 
attributes that are already loaded, populating any expired or not-yet-loaded attributes 
all the way down the hierarchy.   Previously it tried to save time by not descending into 
already loaded subtrees.   This is to better support the use case of using eager loading 
in order to fully populate a tree, such that it can be detached and sent to a cache in a 
fully loaded state.  It is also behaviorally closer to the spirit of "I asked for X, 
I should get X", i.e. if you say subqueryload(), you'll get your subquery no matter 
what.

Other than that there were a *lot* of ORM fixes, most of which have been also applied to the 
0.6 branch and will be in 0.6.9.  Also some additional 0.6->0.7 regressions fixed, and 
some fixes to the new "Mutable" extension including one which was kind of a show 
stopper.

Download SQLAlchemy 0.7.2 at:

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

Changelog follows.

0.7.2
=====
- orm
  - Feature enhancement: joined and subquery
    loading will now traverse already-present related
    objects and collections in search of unpopulated
    attributes throughout the scope of the eager load
    being defined, so that the eager loading that is
    specified via mappings or query options
    unconditionally takes place for the full depth,
    populating whatever is not already populated.
    Previously, this traversal would stop if a related
    object or collection were already present leading
    to inconsistent behavior (though would save on
    loads/cycles for an already-loaded graph). For a
    subqueryload, this means that the additional
    SELECT statements emitted by subqueryload will
    invoke unconditionally, no matter how much of the
    existing graph is already present (hence the
    controversy). The previous behavior of "stopping"
    is still in effect when a query is the result of
    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
    _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
    against a joined table structure.  [ticket:2195]

  - Fixed bug where query.join() + aliased=True
    from a joined-inh structure to itself on
    relationship() with join condition on the child
    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
    accept the None but obviously nothing is
    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
    ObjectDeletedError instead of failing later
    on; improved the message in ObjectDeletedError
    to include other conditions besides a simple
    "delete". [ticket:2191]

  - Fixed regression from 0.6 where a get history
    operation on some relationship() based attributes
    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
    is not a single integer.  [ticket:2228]
    Also in 0.6.9

  - Fixed bug whereby the source clause
    used by query.join() would be inconsistent
    if against a column expression that combined
    multiple entities together.  [ticket:2197]
    Also in 0.6.9

  - Fixed bug whereby if a mapped class
    redefined __hash__() or __eq__() to something
    non-standard, which is a supported use case
    as SQLA should never consult these,
    the methods would be consulted if the class
    was part of a "composite" (i.e. non-single-entity)
    result set.  [ticket:2215]
    Also in 0.6.9.

  - 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

  - Fixed subtle bug that caused SQL to blow
    up if: column_property() against subquery +
    joinedload + LIMIT + order by the column
    property() occurred.  [ticket:2188].
    Also in 0.6.9

  - 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
    the same bindparam.  [ticket:2207].
    Also in 0.6.9.

  - Added the same "columns-only" check to
    mapper.polymorphic_on as used when
    receiving user arguments to
    relationship.order_by, foreign_keys,
    remote_side, etc.

  - Fixed bug whereby comparison of column
    expression to a Query() would not call
    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]

  - Fixed declarative bug where a class inheriting
    from a superclass of the same name would fail
    due to an unnecessary lookup of the name
    in the _decl_class_registry. [ticket:2194]

  - 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
    correspondence in a selectable,
    one with the same labeled subquery repeated, the other
    when the label has been "grouped" and
    loses itself.  Affects [ticket:2188].

- schema
  - 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
    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
    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
    Table would fail if the type had no "affinity"
    value, in particular this would occur when using
    the UUID example on the site that uses TypeEngine
    as the "impl".

  - Added an improved repr() to TypeEngine objects
    that will only display constructor args which
    are positional or kwargs that deviate
    from the default.  [ticket:2209]

- engine
  - Context manager provided by Connection.begin()
    will issue rollback() if the commit() fails,
    not just if an exception occurs.

  - Use urllib.parse_qsl() in Python 2.6 and above,
    no deprecation warning about cgi.parse_qsl()
    [ticket:1682]

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

  - StatementException wrapping will display the
    original exception class in the message.

  - Failures on connect which raise dbapi.Error
    will forward the error to dialect.is_disconnect()
    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]

- sqlite
  - SQLite dialect no longer strips quotes
    off of reflected default value, allowing
    a round trip CREATE TABLE to work.
    This is consistent with other dialects
    that also maintain the exact form of
    the default.  [ticket:2189]

- postgresql
  - 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
    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.
    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
    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
    event.  [ticket:2201]

  - repaired the oracle.RAW type which did not
    generate the correct DDL.  [ticket:2220]
    Also in 0.6.9.

  - added CURRENT to reserved word list.
    [ticket:2212] Also in 0.6.9.

-ext
  - Fixed bug in the mutable extension whereby
    if the same type were used twice in one
    mapping, the attributes beyond the first
    would not get instrumented.

  - Fixed bug in the mutable extension whereby
    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.

- examples
  - Repaired the examples/versioning test runner
    to not rely upon SQLAlchemy test libs,
    nosetests must be run from within
    examples/versioning to get around setup.cfg
    breaking it.

  - Tweak to examples/versioning to pick the
    correct foreign key in a multi-level
    inheritance situation.

  - Fixed the attribute shard example to check
    for bind param callable correctly in 0.7
    style.

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


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

Reply via email to