SQLAlchemy 0.6beta2 is now available.    This beta may be the last before the 
0.6.0 final release.   We've hopefully gotten every largish change into the 
release as possible so that people can test.   0.6 is already running on a 
number of production servers and is already widely tested on mainstream 
platforms.

Big new things in this release include:

- dialects for Sybase, as well as MS-SQL against mxODBC and pymssql.   The 
Sybase and mxODBC dialects are still under construction but are largely 
functional.
- optional C extensions which implement ResultProxy internals natively
- seamless Python 3 installation
- a ton of other stuff, summarized in the changelog below

A full summary of all backends and an assessment of their stability can be 
viewed on the site at:

http://www.sqlalchemy.org/docs/dbengine.html#supported-databases

Download SQLAlchemy 0.6beta2 at:

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


0.6beta2
========

- py3k
  - Improved the installation/test setup regarding Python 3,
    now that Distribute runs on Py3k.   distribute_setup.py
    is now included.  See README.py3k for Python 3 installation/
    testing instructions.
    
- orm
  - The official name for the relation() function is now
    relationship(), to eliminate confusion over the relational
    algebra term.  relation() however will remain available 
    in equal capacity for the foreseeable future.  [ticket:1740]

  - Added "version_id_generator" argument to Mapper, this is a
    callable that, given the current value of the "version_id_col",
    returns the next version number.  Can be used for alternate
    versioning schemes such as uuid, timestamps.  [ticket:1692]
  
  - added "lockmode" kw argument to Session.refresh(), will
    pass through the string value to Query the same as  
    in with_lockmode(), will also do version check for a 
    version_id_col-enabled mapping.

  - Fixed bug whereby calling query(A).join(A.bs).add_entity(B)
    in a joined inheritance scenario would double-add B as a 
    target and produce an invalid query.  [ticket:1188]

  - Fixed bug in session.rollback() which involved not removing
    formerly "pending" objects from the session before
    re-integrating "deleted" objects, typically occured with
    natural primary keys. If there was a primary key conflict
    between them, the attach of the deleted would fail
    internally. The formerly "pending" objects are now expunged
    first. [ticket:1674]

  - Removed a lot of logging that nobody really cares about,
    logging that remains will respond to live changes in the
    log level.  No significant overhead is added.  [ticket:1719]

  - Fixed bug in session.merge() which prevented dict-like
    collections from merging.
    
  - session.merge() works with relations that specifically
    don't include "merge" in their cascade options - the target
    is ignored completely.
    
  - session.merge() will not expire existing scalar attributes
    on an existing target if the target has a value for that
    attribute, even if the incoming merged doesn't have
    a value for the attribute.  This prevents unnecessary loads
    on existing items.  Will still mark the attr as expired
    if the destination doesn't have the attr, though, which
    fulfills some contracts of deferred cols.  [ticket:1681]

  - The "allow_null_pks" flag is now called "allow_partial_pks",
    defaults to True, acts like it did in 0.5 again.  Except,
    it also is implemented within merge() such that a SELECT
    won't be issued for an incoming instance with partially
    NULL primary key if the flag is False.  [ticket:1680]
  
  - Fixed bug in 0.6-reworked "many-to-one" optimizations
    such that a many-to-one that is against a non-primary key
    column on the remote table (i.e. foreign key against a 
    UNIQUE column) will pull the "old" value in from the
    database during a change, since if it's in the session
    we will need it for proper history/backref accounting,
    and we can't pull from the local identity map on a 
    non-primary key column. [ticket:1737]
    
  - fixed internal error which would occur if calling has()
    or similar complex expression on a single-table inheritance
    relation(). [ticket:1731]
    
  - query.one() no longer applies LIMIT to the query, this to
    ensure that it fully counts all object identities present
    in the result, even in the case where joins may conceal
    multiple identities for two or more rows.  As a bonus,
    one() can now also be called with a query that issued
    from_statement() to start with since it no longer modifies
    the query.  [ticket:1688]

  - query.get() now returns None if queried for an identifier
    that is present in the identity map with a different class 
    than the one requested, i.e. when using polymorphic loading.  
    [ticket:1727]
    
  - A major fix in query.join(), when the "on" clause is an
    attribute of an aliased() construct, but there is already
    an existing join made out to a compatible target, query properly
    joins to the right aliased() construct instead of sticking
    onto the right side of the existing join.  [ticket:1706]
    
  - Slight improvement to the fix for [ticket:1362] to not issue 
    needless updates of the primary key column during a so-called
    "row switch" operation, i.e. add + delete of two objects
    with the same PK.

  - Now uses sqlalchemy.orm.exc.DetachedInstanceError when an 
    attribute load or refresh action fails due to object
    being detached from any Session.   UnboundExecutionError
    is specific to engines bound to sessions and statements.
    
  - Query called in the context of an expression will render
    disambiguating labels in all cases.    Note that this does
    not apply to the existing .statement and .subquery()
    accessor/method, which still honors the .with_labels()
    setting that defaults to False.  
     
  - Query.union() retains disambiguating labels within the
    returned statement, thus avoiding various SQL composition
    errors which can result from column name conflicts.
    [ticket:1676]

  - Fixed bug in attribute history that inadvertently invoked
    __eq__ on mapped instances.

  - Some internal streamlining of object loading grants a 
    small speedup for large results, estimates are around 
    10-15%.   Gave the "state" internals a good solid 
    cleanup with less complexity, datamembers, 
    method calls, blank dictionary creates.

  - Documentation clarification for query.delete()
    [ticket:1689]

  - Fixed cascade bug in many-to-one relation() when attribute
    was set to None, introduced in r6711 (cascade deleted
    items into session during add()).

  - Calling query.order_by() or query.distinct() before calling
    query.select_from(), query.with_polymorphic(), or
    query.from_statement() raises an exception now instead of 
    silently dropping those criterion. [ticket:1736]
    
  - query.scalar() now raises an exception if more than one 
    row is returned.  All other behavior remains the same.
    [ticket:1735]

  - Fixed bug which caused "row switch" logic, that is an 
    INSERT and DELETE replaced by an UPDATE, to fail when 
    version_id_col was in use. [ticket:1692]
    
- sql
  - join() will now simulate a NATURAL JOIN by default.  Meaning,
    if the left side is a join, it will attempt to join the right
    side to the rightmost side of the left first, and not raise
    any exceptions about ambiguous join conditions if successful
    even if there are further join targets across the rest of
    the left.  [ticket:1714]
    
  - The most common result processors conversion function were
    moved to the new "processors" module.  Dialect authors are
    encouraged to use those functions whenever they correspond
    to their needs instead of implementing custom ones.

  - SchemaType and subclasses Boolean, Enum are now serializable,
    including their ddl listener and other event callables.
    [ticket:1694] [ticket:1698]

  - Some platforms will now interpret certain literal values 
    as non-bind parameters, rendered literally into the SQL
    statement.   This to support strict SQL-92 rules that are 
    enforced by some platforms including MS-SQL and Sybase.
    In this model, bind parameters aren't allowed in the
    columns clause of a SELECT, nor are certain ambiguous
    expressions like "?=?".  When this mode is enabled, the base
    compiler will render the binds as inline literals, but only across
    strings and numeric values.  Other types such as dates
    will raise an error, unless the dialect subclass defines
    a literal rendering function for those.  The bind parameter
    must have an embedded literal value already or an error
    is raised (i.e. won't work with straight bindparam('x')).
    Dialects can also expand upon the areas where binds are not 
    accepted, such as within argument lists of functions 
    (which don't work on MS-SQL when native SQL binding is used).
    
  - Added "unicode_errors" parameter to String, Unicode, etc.
    Behaves like the 'errors' keyword argument to
    the standard library's string.decode() functions.   This flag
    requires that `convert_unicode` is set to `"force"` - otherwise,
    SQLAlchemy is not guaranteed to handle the task of unicode
    conversion.   Note that this flag adds significant performance
    overhead to row-fetching operations for backends that already
    return unicode objects natively (which most DBAPIs do).  This
    flag should only be used as an absolute last resort for reading
    strings from a column with varied or corrupted encodings,
    which only applies to databases that accept invalid encodings 
    in the first place (i.e. MySQL. *not* PG, Sqlite, etc.)

  - Added math negation operator support, -x.
  
  - FunctionElement subclasses are now directly executable the
    same way any func.foo() construct is, with automatic 
    SELECT being applied when passed to execute().
    
  - The "type" and "bind" keyword arguments of a func.foo() 
    construct are now local to "func." constructs and are 
    not part of the FunctionElement base class, allowing 
    a "type" to be handled in a custom constructor or 
    class-level variable.
    
  - Restored the keys() method to ResultProxy.
  
  - The type/expression system now does a more complete job
    of determining the return type from an expression
    as well as the adaptation of the Python operator into 
    a SQL operator, based on the full left/right/operator
    of the given expression.  In particular
    the date/time/interval system created for Postgresql
    EXTRACT in [ticket:1647] has now been generalized into
    the type system.   The previous behavior which often
    occured of an expression "column + literal" forcing
    the type of "literal" to be the same as that of "column"
    will now usually not occur - the type of 
    "literal" is first derived from the Python type of the 
    literal, assuming standard native Python types + date 
    types, before falling back to that of the known type
    on the other side of the expression.  If the 
    "fallback" type is compatible (i.e. CHAR from String),
    the literal side will use that.  TypeDecorator
    types override this by default to coerce the "literal"
    side unconditionally, which can be changed by implementing
    the coerce_compared_value() method. Also part of 
    [ticket:1683].

  - Made sqlalchemy.sql.expressions.Executable part of public 
    API, used for any expression construct that can be sent to
    execute().  FunctionElement now inherits Executable so that
    it gains execution_options(), which are also propagated
    to the select() that's generated within execute().
    Executable in turn subclasses _Generative which marks
    any ClauseElement that supports the @_generative
    decorator - these may also become "public" for the benefit
    of the compiler extension at some point.

  - A change to the solution for [ticket:1579] - an end-user
    defined bind parameter name that directly conflicts with 
    a column-named bind generated directly from the SET or
    VALUES clause of an update/insert generates a compile error.
    This reduces call counts and eliminates some cases where
    undesirable name conflicts could still occur.

  - Column() requires a type if it has no foreign keys (this is 
    not new).  An error is now raised if a Column() has no type
    and no foreign keys.  [ticket:1705]
    
  - the "scale" argument of the Numeric() type is honored when 
    coercing a returned floating point value into a string 
    on its way to Decimal - this allows accuracy to function
    on SQLite, MySQL.  [ticket:1717]

  - the copy() method of Column now copies over uninitialized
    "on table attach" events.  Helps with the new declarative
    "mixin" capability.
    
- engines
  - Added an optional C extension to speed up the sql layer by
    reimplementing RowProxy and the most common result processors.
    The actual speedups will depend heavily on your DBAPI and
    the mix of datatypes used in your tables, and can vary from
    a 30% improvement to more than 200%.  It also provides a modest
    (~15-20%) indirect improvement to ORM speed for large queries.
    Note that it is *not* built/installed by default.
    See README for installation instructions.

  - the execution sequence pulls all rowcount/last inserted ID
    info from the cursor before commit() is called on the 
    DBAPI connection in an "autocommit" scenario.  This helps 
    mxodbc with rowcount and is probably a good idea overall.
    
  - Opened up logging a bit such that isEnabledFor() is called 
    more often, so that changes to the log level for engine/pool
    will be reflected on next connect.   This adds a small 
    amount of method call overhead.  It's negligible and will make
    life a lot easier for all those situations when logging 
    just happens to be configured after create_engine() is called.
    [ticket:1719]
    
  - The assert_unicode flag is deprecated.  SQLAlchemy will raise
    a warning in all cases where it is asked to encode a non-unicode
    Python string, as well as when a Unicode or UnicodeType type
    is explicitly passed a bytestring.  The String type will do nothing 
    for DBAPIs that already accept Python unicode objects.

  - Bind parameters are sent as a tuple instead of a list. Some
    backend drivers will not accept bind parameters as a list.

  - threadlocal engine wasn't properly closing the connection
    upon close() - fixed that.

  - Transaction object doesn't rollback or commit if it isn't 
    "active", allows more accurate nesting of begin/rollback/commit.

  - Python unicode objects as binds result in the Unicode type, 
    not string, thus eliminating a certain class of unicode errors
    on drivers that don't support unicode binds.

  - Added "logging_name" argument to create_engine(), Pool() constructor
    as well as "pool_logging_name" argument to create_engine() which
    filters down to that of Pool.   Issues the given string name
    within the "name" field of logging messages instead of the default
    hex identifier string.  [ticket:1555]
    
  - The visit_pool() method of Dialect is removed, and replaced with
    on_connect().  This method returns a callable which receives
    the raw DBAPI connection after each one is created.   The callable
    is assembled into a first_connect/connect pool listener by the 
    connection strategy if non-None.   Provides a simpler interface 
    for dialects.
    
  - StaticPool now initializes, disposes and recreates without 
    opening a new connection - the connection is only opened when 
    first requested. dispose() also works on AssertionPool now.
    [ticket:1728]
    
- metadata
  - Added the ability to strip schema information when using
    "tometadata" by passing "schema=None" as an argument. If schema
    is not specified then the table's schema is retained.
    [ticket: 1673]

- declarative
  - DeclarativeMeta exclusively uses cls.__dict__ (not dict_) 
    as the source of class information; _as_declarative exclusively 
    uses the  dict_ passed to it as the source of class information 
    (which when using DeclarativeMeta is cls.__dict__).  This should 
    in theory make it easier for custom metaclasses to modify
    the state passed into _as_declarative.

  - declarative now accepts mixin classes directly, as a means
    to provide common functional and column-based elements on
    all subclasses, as well as a means to propagate a fixed
    set of __table_args__ or __mapper_args__ to subclasses.  
    For custom combinations of __table_args__/__mapper_args__ from
    an inherited mixin to local, descriptors can now be used.
    New details are all up in the Declarative documentation.
    Thanks to Chris Withers for putting up with my strife 
    on this. [ticket:1707]
    
  - the __mapper_args__ dict is copied when propagating to a subclass,
    and is taken straight off the class __dict__ to avoid any
    propagation from the parent.  mapper inheritance already
    propagates the things you want from the parent mapper.
    [ticket:1393]

  - An exception is raised when a single-table subclass specifies
    a column that is already present on the base class.
    [ticket:1732]
    
- mysql
  - Fixed reflection bug whereby when COLLATE was present, 
    nullable flag and server defaults would not be reflected.
    [ticket:1655]

  - Fixed reflection of TINYINT(1) "boolean" columns defined with
    integer flags like UNSIGNED.

  - Further fixes for the mysql-connector dialect.  [ticket:1668]
  
  - Composite PK table on InnoDB where the "autoincrement" column
    isn't first will emit an explicit "KEY" phrase within 
    CREATE TABLE thereby avoiding errors, [ticket:1496]

  - Added reflection/create table support for a wide range
    of MySQL keywords.  [ticket:1634]
  
  - Fixed import error which could occur reflecting tables on
    a Windows host [ticket:1580]
    
- mssql
  - Re-established support for the pymssql dialect.

  - Various fixes for implicit returning, reflection,
    etc. - the MS-SQL dialects aren't quite complete
    in 0.6 yet (but are close)
  
  - Added basic support for mxODBC [ticket:1710].
  
  - Removed the text_as_varchar option.

- oracle
   - "out" parameters require a type that is supported by
     cx_oracle.  An error will be raised if no cx_oracle
     type can be found.

   - Oracle 'DATE' now does not perform any result processing,
     as the DATE type in Oracle stores full date+time objects,
     that's what you'll get.  Note that the generic types.Date
     type *will* still call value.date() on incoming values, 
     however.  When reflecting a table, the reflected type
     will be 'DATE'.

   - Added preliminary support for Oracle's WITH_UNICODE
     mode.  At the very least this establishes initial
     support for cx_Oracle with Python 3.  When WITH_UNICODE
     mode is used in Python 2.xx, a large and scary warning
     is emitted asking that the user seriously consider
     the usage of this difficult mode of operation.
     [ticket:1670]
  
   - The except_() method now renders as MINUS on Oracle,
     which is more or less equivalent on that platform.
     [ticket:1712]
   
   - Added support for rendering and reflecting 
     TIMESTAMP WITH TIME ZONE, i.e. TIMESTAMP(timezone=True).
     [ticket:651]
     
   - Oracle INTERVAL type can now be reflected.
     
- sqlite
   - Added "native_datetime=True" flag to create_engine().
     This will cause the DATE and TIMESTAMP types to skip 
     all bind parameter and result row processing, under 
     the assumption that PARSE_DECLTYPES has been enabled 
     on the connection.  Note that this is not entirely
     compatible with the "func.current_date()", which 
     will be returned as a string. [ticket:1685]

- sybase
   - Implemented a preliminary working dialect for Sybase,
     with sub-implementations for Python-Sybase as well
     as Pyodbc.  Handles table
     creates/drops and basic round trip functionality.
     Does not yet include reflection or comprehensive
     support of unicode/special expressions/etc.
     
- examples
   - Changed the beaker cache example a bit to have a separate
     RelationCache option for lazyload caching.  This object
     does a lookup among any number of potential attributes
     more efficiently by grouping several into a common structure.
     Both FromCache and RelationCache are simpler individually.

- documentation
   - Major cleanup work in the docs to link class, function, and
     method names into the API docs. [ticket:1700/1702/1703]

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