=======
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
- [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
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. """
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."""