From: Mike Bayer Date: Mon, 23 Apr 2012 16:03:54 +0000 (-0400) Subject: merge patch for [ticket:2208]. This still needs documentation. X-Git-Tag: rel_0_8_0b1~474 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=54017d9de202ed67072a352ce2f6dbfd74bf48f3;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git merge patch for [ticket:2208]. This still needs documentation. --- 54017d9de202ed67072a352ce2f6dbfd74bf48f3 diff --cc CHANGES index 8fba962d4e,88ddad8f8f..44f7a94f9e --- a/CHANGES +++ b/CHANGES @@@ -3,41 -3,9 +3,52 @@@ ======= CHANGES ======= -0.7.7 -===== +0.7.7 - 0.7.xx +============== + +Changes which apply to 0.7.7 and subsequent versions of 0.7 +are listed in the CHANGES file within the 0.7 branch. All +those changes which are also in the 0.8 series (which is typically +all of them) are listed inline within the 0.8 changes above, +those which apply to an 0.7 release are noted. + +0.8.0b1 +======= - orm + - [feature] Major rewrite of relationship() + internals now allow join conditions which + include columns pointing to themselves + within composite foreign keys. A new + API for very specialized primaryjoin conditions + is added, allowing conditions based on + SQL functions, CAST, etc. to be handled + by placing the annotation functions + remote() and foreign() inline within the + expression when necessary. Previous recipes + using the semi-private _local_remote_pairs + approach can be upgraded to this new + approach. [ticket:1401] + ++ - [feature] Added new core function "inspect()", ++ which serves as a generic gateway to ++ introspection into mappers, objects, ++ others. The Mapper and InstanceState ++ objects have been enhanced with a public ++ API that allows inspection of mapped ++ attributes, including filters for column-bound ++ or relationship-bound properties, inspection ++ of current object state, history of ++ attributes, etc. [ticket:2208] ++ + - [feature] Query now "auto correlates" by + default in the same way as select() does. + Previously, a Query used as a subquery + in another would require the correlate() + method be called explicitly in order to + correlate a table on the inside to the + outside. As always, correlate(None) + disables correlation. [ticket:2179] + - [feature] Added prefix_with() method to Query, calls upon select().prefix_with() to allow placement of MySQL SELECT @@@ -77,9 -27,8 +88,13 @@@ - [bug] Fixed bug which would prevent OrderingList from being pickleable [ticket:2454]. Courtesy Jeff Dairiki + also in 0.7.7. - sql ++ - [feature] The Inspector object can now be ++ acquired using the new inspect() service, ++ part of [ticket:2208] ++ - [bug] Removed warning when Index is created with no columns; while this might not be what the user intended, it is a valid use case diff --cc lib/sqlalchemy/__init__.py index 962a1a761b,ee7bf4c6f9..422d9e43e8 --- a/lib/sqlalchemy/__init__.py +++ b/lib/sqlalchemy/__init__.py @@@ -115,11 -117,11 +117,11 @@@ from sqlalchemy.engine import create_en __all__ = sorted(name for name, obj in locals().items() - if not (name.startswith('_') or inspect.ismodule(obj))) + if not (name.startswith('_') or _inspect.ismodule(obj))) -__version__ = '0.7.7' +__version__ = '0.8.0b1' - del inspect, sys + del _inspect, sys from sqlalchemy import util as _sa_util _sa_util.importlater.resolve_all() diff --cc lib/sqlalchemy/orm/attributes.py index ec0b84a60d,c351748df4..d756824439 --- a/lib/sqlalchemy/orm/attributes.py +++ b/lib/sqlalchemy/orm/attributes.py @@@ -22,79 -22,61 +22,78 @@@ from sqlalchemy.orm import interfaces, mapperutil = util.importlater("sqlalchemy.orm", "util") -PASSIVE_NO_RESULT = util.symbol('PASSIVE_NO_RESULT') -ATTR_WAS_SET = util.symbol('ATTR_WAS_SET') -ATTR_EMPTY = util.symbol('ATTR_EMPTY') -NO_VALUE = util.symbol('NO_VALUE') -NEVER_SET = util.symbol('NEVER_SET') - -PASSIVE_RETURN_NEVER_SET = util.symbol('PASSIVE_RETURN_NEVER_SET', -"""Symbol indicating that loader callables can be -fired off, but if no callable is applicable and no value is -present, the attribute should remain non-initialized. -NEVER_SET is returned in this case. -""") - -PASSIVE_NO_INITIALIZE = util.symbol('PASSIVE_NO_INITIALIZE', -"""Symbol indicating that loader callables should - not be fired off, and a non-initialized attribute - should remain that way. -""") - -PASSIVE_NO_FETCH = util.symbol('PASSIVE_NO_FETCH', -"""Symbol indicating that loader callables should not emit SQL, - but a value can be fetched from the current session. - - Non-initialized attributes should be initialized to an empty value. +PASSIVE_NO_RESULT = util.symbol('PASSIVE_NO_RESULT', +"""Symbol returned by a loader callable or other attribute/history +retrieval operation when a value could not be determined, based +on loader callable flags. +""" +) +ATTR_WAS_SET = util.symbol('ATTR_WAS_SET', +"""Symbol returned by a loader callable to indicate the +retrieved value, or values, were assigned to their attributes +on the target object. """) -PASSIVE_NO_FETCH_RELATED = util.symbol('PASSIVE_NO_FETCH_RELATED', -"""Symbol indicating that loader callables should not emit SQL for - loading a related object, but can refresh the attributes of the local - instance in order to locate a related object in the current session. - - Non-initialized attributes should be initialized to an empty value. - - The unit of work uses this mode to check if history is present - on many-to-one attributes with minimal SQL emitted. - +ATTR_EMPTY = util.symbol('ATTR_EMPTY', +"""Symbol used internally to indicate an attribute had no callable. """) -PASSIVE_ONLY_PERSISTENT = util.symbol('PASSIVE_ONLY_PERSISTENT', -"""Symbol indicating that loader callables should only fire off for - parent objects which are persistent (i.e., have a database - identity). - - Load operations for the "previous" value of an attribute make - use of this flag during change events. - -""") +NO_VALUE = util.symbol('NO_VALUE', +"""Symbol which may be placed as the 'previous' value of an attribute, +indicating no value was loaded for an attribute when it was modified, +and flags indicated we were not to load it. +""" +) -PASSIVE_OFF = util.symbol('PASSIVE_OFF', -"""Symbol indicating that loader callables should be executed - normally. +NEVER_SET = util.symbol('NEVER_SET', +"""Symbol which may be placed as the 'previous' value of an attribute +indicating that the attribute had not been assigned to previously. +""" +) + +CALLABLES_OK = util.symbol("CALLABLES_OK", +"""Loader callables can be fired off if a value +is not present.""", canonical=1 +) + +SQL_OK = util.symbol("SQL_OK", +"""Loader callables can emit SQL at least on scalar value +attributes.""", canonical=2) + +RELATED_OBJECT_OK = util.symbol("RELATED_OBJECT_OK", +"""callables can use SQL to load related objects as well +as scalar value attributes. +""", canonical=4 +) + +INIT_OK = util.symbol("INIT_OK", +"""Attributes should be initialized with a blank +value (None or an empty collection) upon get, if no other +value can be obtained. +""", canonical=8 +) + +NON_PERSISTENT_OK = util.symbol("NON_PERSISTENT_OK", +"""callables can be emitted if the parent is not persistent.""", +canonical=16 +) + + +# pre-packaged sets of flags used as inputs +PASSIVE_OFF = RELATED_OBJECT_OK | \ + NON_PERSISTENT_OK | \ + INIT_OK | \ + CALLABLES_OK | \ + SQL_OK + +PASSIVE_RETURN_NEVER_SET = PASSIVE_OFF ^ INIT_OK +PASSIVE_NO_INITIALIZE = PASSIVE_RETURN_NEVER_SET ^ CALLABLES_OK +PASSIVE_NO_FETCH = PASSIVE_OFF ^ SQL_OK +PASSIVE_NO_FETCH_RELATED = PASSIVE_OFF ^ RELATED_OBJECT_OK +PASSIVE_ONLY_PERSISTENT = PASSIVE_OFF ^ NON_PERSISTENT_OK -""") - class QueryableAttribute(interfaces.PropComparator): """Base class for class-bound attributes. """ diff --cc lib/sqlalchemy/orm/state.py index 30a08faba0,a8c9dea06c..64fca87156 --- a/lib/sqlalchemy/orm/state.py +++ b/lib/sqlalchemy/orm/state.py @@@ -17,13 -17,15 +17,13 @@@ from sqlalchemy import uti from sqlalchemy.orm import exc as orm_exc, attributes, interfaces,\ util as orm_util --from sqlalchemy.orm.attributes import PASSIVE_OFF, PASSIVE_NO_RESULT, \ - SQL_OK, NEVER_SET, ATTR_WAS_SET, NO_VALUE - PASSIVE_NO_FETCH, NEVER_SET, ATTR_WAS_SET, NO_VALUE,\ ++from sqlalchemy.orm.attributes import PASSIVE_NO_RESULT, \ ++ SQL_OK, NEVER_SET, ATTR_WAS_SET, NO_VALUE,\ + PASSIVE_NO_INITIALIZE mapperlib = util.importlater("sqlalchemy.orm", "mapperlib") - - import sys + sessionlib = util.importlater("sqlalchemy.orm", "session") -import sys - class InstanceState(object): """tracks state information at the instance level."""