mirror of
https://github.com/sqlalchemy/sqlalchemy.git
synced 2026-06-01 13:28:30 -04:00
just a pep8 pass of lib/sqlalchemy/orm/
This commit is contained in:
@@ -165,6 +165,7 @@ def create_session(bind=None, **kwargs):
|
||||
kwargs.setdefault('expire_on_commit', False)
|
||||
return Session(bind=bind, **kwargs)
|
||||
|
||||
|
||||
def relationship(argument, secondary=None, **kwargs):
|
||||
"""Provide a relationship of a primary Mapper to a secondary Mapper.
|
||||
|
||||
@@ -179,10 +180,10 @@ def relationship(argument, secondary=None, **kwargs):
|
||||
|
||||
Some arguments accepted by :func:`.relationship` optionally accept a
|
||||
callable function, which when called produces the desired value.
|
||||
The callable is invoked by the parent :class:`.Mapper` at "mapper initialization"
|
||||
time, which happens only when mappers are first used, and is assumed
|
||||
to be after all mappings have been constructed. This can be used
|
||||
to resolve order-of-declaration and other dependency issues, such as
|
||||
The callable is invoked by the parent :class:`.Mapper` at "mapper
|
||||
initialization" time, which happens only when mappers are first used, and
|
||||
is assumed to be after all mappings have been constructed. This can be
|
||||
used to resolve order-of-declaration and other dependency issues, such as
|
||||
if ``Child`` is declared below ``Parent`` in the same file::
|
||||
|
||||
mapper(Parent, properties={
|
||||
@@ -195,8 +196,8 @@ def relationship(argument, secondary=None, **kwargs):
|
||||
These string arguments are converted into callables that evaluate
|
||||
the string as Python code, using the Declarative
|
||||
class-registry as a namespace. This allows the lookup of related
|
||||
classes to be automatic via their string name, and removes the need to import
|
||||
related classes at all into the local module space::
|
||||
classes to be automatic via their string name, and removes the need to
|
||||
import related classes at all into the local module space::
|
||||
|
||||
from sqlalchemy.ext.declarative import declarative_base
|
||||
|
||||
@@ -211,8 +212,8 @@ def relationship(argument, secondary=None, **kwargs):
|
||||
:func:`.relationship` is at :ref:`relationship_config_toplevel`.
|
||||
|
||||
:param argument:
|
||||
a mapped class, or actual :class:`.Mapper` instance, representing the target of
|
||||
the relationship.
|
||||
a mapped class, or actual :class:`.Mapper` instance, representing the
|
||||
target of the relationship.
|
||||
|
||||
``argument`` may also be passed as a callable function
|
||||
which is evaluated at mapper initialization time, and may be passed as a
|
||||
@@ -362,8 +363,8 @@ def relationship(argument, secondary=None, **kwargs):
|
||||
|
||||
There are only two use cases for ``foreign_keys`` - one, when it is not
|
||||
convenient for :class:`.Table` metadata to contain its own foreign key
|
||||
metadata (which should be almost never, unless reflecting a large amount of
|
||||
tables from a MySQL MyISAM schema, or a schema that doesn't actually
|
||||
metadata (which should be almost never, unless reflecting a large amount
|
||||
of tables from a MySQL MyISAM schema, or a schema that doesn't actually
|
||||
have foreign keys on it). The other is for extremely
|
||||
rare and exotic composite foreign key setups where some columns
|
||||
should artificially not be considered as foreign.
|
||||
@@ -621,16 +622,19 @@ def relationship(argument, secondary=None, **kwargs):
|
||||
case, use an alternative method.
|
||||
|
||||
.. versionchanged:: 0.6
|
||||
:func:`relationship` was renamed from its previous name :func:`relation`.
|
||||
:func:`relationship` was renamed from its previous name
|
||||
:func:`relation`.
|
||||
|
||||
"""
|
||||
return RelationshipProperty(argument, secondary=secondary, **kwargs)
|
||||
|
||||
|
||||
def relation(*arg, **kw):
|
||||
"""A synonym for :func:`relationship`."""
|
||||
|
||||
return relationship(*arg, **kw)
|
||||
|
||||
|
||||
def dynamic_loader(argument, **kw):
|
||||
"""Construct a dynamically-loading mapper property.
|
||||
|
||||
@@ -650,6 +654,7 @@ def dynamic_loader(argument, **kw):
|
||||
kw['lazy'] = 'dynamic'
|
||||
return relationship(argument, **kw)
|
||||
|
||||
|
||||
def column_property(*cols, **kw):
|
||||
"""Provide a column-level property for use with a Mapper.
|
||||
|
||||
@@ -728,6 +733,7 @@ def column_property(*cols, **kw):
|
||||
|
||||
return ColumnProperty(*cols, **kw)
|
||||
|
||||
|
||||
def composite(class_, *cols, **kwargs):
|
||||
"""Return a composite column-based property for use with a Mapper.
|
||||
|
||||
@@ -784,8 +790,8 @@ def composite(class_, *cols, **kwargs):
|
||||
|
||||
|
||||
def backref(name, **kwargs):
|
||||
"""Create a back reference with explicit keyword arguments, which are the same
|
||||
arguments one can send to :func:`relationship`.
|
||||
"""Create a back reference with explicit keyword arguments, which are the
|
||||
same arguments one can send to :func:`relationship`.
|
||||
|
||||
Used with the ``backref`` keyword argument to :func:`relationship` in
|
||||
place of a string argument, e.g.::
|
||||
@@ -795,6 +801,7 @@ def backref(name, **kwargs):
|
||||
"""
|
||||
return (name, kwargs)
|
||||
|
||||
|
||||
def deferred(*columns, **kwargs):
|
||||
"""Return a :class:`.DeferredColumnProperty`, which indicates this
|
||||
object attributes should only be loaded from its corresponding
|
||||
@@ -809,6 +816,7 @@ def deferred(*columns, **kwargs):
|
||||
"""
|
||||
return ColumnProperty(deferred=True, *columns, **kwargs)
|
||||
|
||||
|
||||
def mapper(class_, local_table=None, *args, **params):
|
||||
"""Return a new :class:`~.Mapper` object.
|
||||
|
||||
@@ -864,9 +872,9 @@ def mapper(class_, local_table=None, *args, **params):
|
||||
this mapper inherits from another mapper using single-table
|
||||
inheritance. When using Declarative, this argument is
|
||||
automatically passed by the extension, based on what
|
||||
is configured via the ``__table__`` argument or via the :class:`.Table`
|
||||
produced as a result of the ``__tablename__`` and :class:`.Column`
|
||||
arguments present.
|
||||
is configured via the ``__table__`` argument or via the
|
||||
:class:`.Table` produced as a result of the ``__tablename__``
|
||||
and :class:`.Column` arguments present.
|
||||
|
||||
:param always_refresh: If True, all query operations for this mapped
|
||||
class will overwrite all data within object instances that already
|
||||
@@ -910,9 +918,9 @@ def mapper(class_, local_table=None, *args, **params):
|
||||
See :ref:`include_exclude_cols` for an example.
|
||||
|
||||
:param extension: A :class:`.MapperExtension` instance or
|
||||
list of :class:`.MapperExtension`
|
||||
instances which will be applied to all operations by this
|
||||
:class:`.Mapper`. **Deprecated.** Please see :class:`.MapperEvents`.
|
||||
list of :class:`.MapperExtension` instances which will be applied
|
||||
to all operations by this :class:`.Mapper`. **Deprecated.**
|
||||
Please see :class:`.MapperEvents`.
|
||||
|
||||
:param include_properties: An inclusive list or set of string column
|
||||
names to map.
|
||||
@@ -921,8 +929,8 @@ def mapper(class_, local_table=None, *args, **params):
|
||||
|
||||
:param inherits: A mapped class or the corresponding :class:`.Mapper`
|
||||
of one indicating a superclass to which this :class:`.Mapper`
|
||||
should *inherit* from. The mapped class here must be a subclass of the
|
||||
other mapper's class. When using Declarative, this argument
|
||||
should *inherit* from. The mapped class here must be a subclass
|
||||
of the other mapper's class. When using Declarative, this argument
|
||||
is passed automatically as a result of the natural class
|
||||
hierarchy of the declared classes.
|
||||
|
||||
@@ -955,8 +963,8 @@ def mapper(class_, local_table=None, *args, **params):
|
||||
ordering.
|
||||
|
||||
:param passive_updates: Indicates UPDATE behavior of foreign key
|
||||
columns when a primary key column changes on a joined-table inheritance
|
||||
mapping. Defaults to ``True``.
|
||||
columns when a primary key column changes on a joined-table
|
||||
inheritance mapping. Defaults to ``True``.
|
||||
|
||||
When True, it is assumed that ON UPDATE CASCADE is configured on
|
||||
the foreign key in the database, and that the database will handle
|
||||
@@ -1092,8 +1100,8 @@ def mapper(class_, local_table=None, *args, **params):
|
||||
that will be used to keep a running version id of mapped entities
|
||||
in the database. This is used during save operations to ensure that
|
||||
no other thread or process has updated the instance during the
|
||||
lifetime of the entity, else a :class:`~sqlalchemy.orm.exc.StaleDataError`
|
||||
exception is
|
||||
lifetime of the entity, else a
|
||||
:class:`~sqlalchemy.orm.exc.StaleDataError` exception is
|
||||
thrown. By default the column must be of :class:`.Integer` type,
|
||||
unless ``version_id_generator`` specifies a new generation
|
||||
algorithm.
|
||||
@@ -1139,6 +1147,7 @@ def mapper(class_, local_table=None, *args, **params):
|
||||
"""
|
||||
return Mapper(class_, local_table, *args, **params)
|
||||
|
||||
|
||||
def synonym(name, map_column=False, descriptor=None,
|
||||
comparator_factory=None, doc=None):
|
||||
"""Denote an attribute name as a synonym to a mapped property.
|
||||
@@ -1182,6 +1191,7 @@ def synonym(name, map_column=False, descriptor=None,
|
||||
comparator_factory=comparator_factory,
|
||||
doc=doc)
|
||||
|
||||
|
||||
def comparable_property(comparator_factory, descriptor=None):
|
||||
"""Provides a method of applying a :class:`.PropComparator`
|
||||
to any Python descriptor attribute.
|
||||
@@ -1222,8 +1232,8 @@ def comparable_property(comparator_factory, descriptor=None):
|
||||
id = Column(Integer, primary_key=True)
|
||||
word = Column(String)
|
||||
word_insensitive = comparable_property(lambda prop, mapper:
|
||||
CaseInsensitiveComparator(mapper.c.word, mapper)
|
||||
)
|
||||
CaseInsensitiveComparator(mapper.c.word, mapper)
|
||||
)
|
||||
|
||||
|
||||
A mapping like the above allows the ``word_insensitive`` attribute
|
||||
@@ -1246,13 +1256,17 @@ def comparable_property(comparator_factory, descriptor=None):
|
||||
"""
|
||||
return ComparableProperty(comparator_factory, descriptor)
|
||||
|
||||
|
||||
@sa_util.deprecated("0.7", message=":func:`.compile_mappers` "
|
||||
"is renamed to :func:`.configure_mappers`")
|
||||
def compile_mappers():
|
||||
"""Initialize the inter-mapper relationships of all mappers that have been defined."""
|
||||
"""Initialize the inter-mapper relationships of all mappers that have
|
||||
been defined.
|
||||
|
||||
"""
|
||||
configure_mappers()
|
||||
|
||||
|
||||
def clear_mappers():
|
||||
"""Remove all mappers from all classes.
|
||||
|
||||
@@ -1285,6 +1299,7 @@ def clear_mappers():
|
||||
finally:
|
||||
mapperlib._CONFIGURE_MUTEX.release()
|
||||
|
||||
|
||||
def joinedload(*keys, **kw):
|
||||
"""Return a ``MapperOption`` that will convert the property of the given
|
||||
name or series of mapped attributes into an joined eager load.
|
||||
@@ -1324,12 +1339,13 @@ def joinedload(*keys, **kw):
|
||||
it **does not affect the query results**. An :meth:`.Query.order_by`
|
||||
or :meth:`.Query.filter` call **cannot** reference these aliased
|
||||
tables - so-called "user space" joins are constructed using
|
||||
:meth:`.Query.join`. The rationale for this is that :func:`joinedload` is only
|
||||
applied in order to affect how related objects or collections are loaded
|
||||
as an optimizing detail - it can be added or removed with no impact
|
||||
on actual results. See the section :ref:`zen_of_eager_loading` for
|
||||
a detailed description of how this is used, including how to use a single
|
||||
explicit JOIN for filtering/ordering and eager loading simultaneously.
|
||||
:meth:`.Query.join`. The rationale for this is that
|
||||
:func:`joinedload` is only applied in order to affect how related
|
||||
objects or collections are loaded as an optimizing detail - it can be
|
||||
added or removed with no impact on actual results. See the section
|
||||
:ref:`zen_of_eager_loading` for a detailed description of how this is
|
||||
used, including how to use a single explicit JOIN for
|
||||
filtering/ordering and eager loading simultaneously.
|
||||
|
||||
See also: :func:`subqueryload`, :func:`lazyload`
|
||||
|
||||
@@ -1343,6 +1359,7 @@ def joinedload(*keys, **kw):
|
||||
else:
|
||||
return strategies.EagerLazyOption(keys, lazy='joined')
|
||||
|
||||
|
||||
def joinedload_all(*keys, **kw):
|
||||
"""Return a ``MapperOption`` that will convert all properties along the
|
||||
given dot-separated path or series of mapped attributes
|
||||
@@ -1360,8 +1377,8 @@ def joinedload_all(*keys, **kw):
|
||||
|
||||
query.options(joinedload_all('orders.items.keywords'))...
|
||||
|
||||
will set all of ``orders``, ``orders.items``, and ``orders.items.keywords`` to
|
||||
load in one joined eager load.
|
||||
will set all of ``orders``, ``orders.items``, and
|
||||
``orders.items.keywords`` to load in one joined eager load.
|
||||
|
||||
Individual descriptors are accepted as arguments as well::
|
||||
|
||||
@@ -1388,10 +1405,12 @@ def eagerload(*args, **kwargs):
|
||||
"""A synonym for :func:`joinedload()`."""
|
||||
return joinedload(*args, **kwargs)
|
||||
|
||||
|
||||
def eagerload_all(*args, **kwargs):
|
||||
"""A synonym for :func:`joinedload_all()`"""
|
||||
return joinedload_all(*args, **kwargs)
|
||||
|
||||
|
||||
def subqueryload(*keys):
|
||||
"""Return a ``MapperOption`` that will convert the property
|
||||
of the given name or series of mapped attributes
|
||||
@@ -1420,6 +1439,7 @@ def subqueryload(*keys):
|
||||
"""
|
||||
return strategies.EagerLazyOption(keys, lazy="subquery")
|
||||
|
||||
|
||||
def subqueryload_all(*keys):
|
||||
"""Return a ``MapperOption`` that will convert all properties along the
|
||||
given dot-separated path or series of mapped attributes
|
||||
@@ -1431,8 +1451,8 @@ def subqueryload_all(*keys):
|
||||
|
||||
query.options(subqueryload_all('orders.items.keywords'))...
|
||||
|
||||
will set all of ``orders``, ``orders.items``, and ``orders.items.keywords`` to
|
||||
load in one subquery eager load.
|
||||
will set all of ``orders``, ``orders.items``, and
|
||||
``orders.items.keywords`` to load in one subquery eager load.
|
||||
|
||||
Individual descriptors are accepted as arguments as well::
|
||||
|
||||
@@ -1444,6 +1464,7 @@ def subqueryload_all(*keys):
|
||||
"""
|
||||
return strategies.EagerLazyOption(keys, lazy="subquery", chained=True)
|
||||
|
||||
|
||||
def lazyload(*keys):
|
||||
"""Return a ``MapperOption`` that will convert the property of the given
|
||||
name or series of mapped attributes into a lazy load.
|
||||
@@ -1455,6 +1476,7 @@ def lazyload(*keys):
|
||||
"""
|
||||
return strategies.EagerLazyOption(keys, lazy=True)
|
||||
|
||||
|
||||
def lazyload_all(*keys):
|
||||
"""Return a ``MapperOption`` that will convert all the properties
|
||||
along the given dot-separated path or series of mapped attributes
|
||||
@@ -1467,6 +1489,7 @@ def lazyload_all(*keys):
|
||||
"""
|
||||
return strategies.EagerLazyOption(keys, lazy=True, chained=True)
|
||||
|
||||
|
||||
def noload(*keys):
|
||||
"""Return a ``MapperOption`` that will convert the property of the
|
||||
given name or series of mapped attributes into a non-load.
|
||||
@@ -1479,6 +1502,7 @@ def noload(*keys):
|
||||
"""
|
||||
return strategies.EagerLazyOption(keys, lazy=None)
|
||||
|
||||
|
||||
def immediateload(*keys):
|
||||
"""Return a ``MapperOption`` that will convert the property of the given
|
||||
name or series of mapped attributes into an immediate load.
|
||||
@@ -1503,6 +1527,7 @@ def immediateload(*keys):
|
||||
"""
|
||||
return strategies.EagerLazyOption(keys, lazy='immediate')
|
||||
|
||||
|
||||
def contains_alias(alias):
|
||||
"""Return a :class:`.MapperOption` that will indicate to the query that
|
||||
the main table has been aliased.
|
||||
@@ -1537,6 +1562,7 @@ def contains_alias(alias):
|
||||
"""
|
||||
return AliasOption(alias)
|
||||
|
||||
|
||||
def contains_eager(*keys, **kwargs):
|
||||
"""Return a ``MapperOption`` that will indicate to the query that
|
||||
the given attribute should be eagerly loaded from columns currently
|
||||
@@ -1580,6 +1606,7 @@ def contains_eager(*keys, **kwargs):
|
||||
propagate_to_loaders=False, chained=True), \
|
||||
strategies.LoadEagerFromAliasOption(keys, alias=alias, chained=True)
|
||||
|
||||
|
||||
def defer(*key):
|
||||
"""Return a :class:`.MapperOption` that will convert the column property
|
||||
of the given name into a deferred load.
|
||||
@@ -1624,6 +1651,7 @@ def defer(*key):
|
||||
"""
|
||||
return strategies.DeferredOption(key, defer=True)
|
||||
|
||||
|
||||
def undefer(*key):
|
||||
"""Return a :class:`.MapperOption` that will convert the column property
|
||||
of the given name into a non-deferred (regular column) load.
|
||||
@@ -1634,28 +1662,29 @@ def undefer(*key):
|
||||
|
||||
from sqlalchemy.orm import undefer
|
||||
|
||||
query(MyClass).options(undefer("attribute_one"),
|
||||
undefer("attribute_two"))
|
||||
query(MyClass).options(
|
||||
undefer("attribute_one"),
|
||||
undefer("attribute_two"))
|
||||
|
||||
A class bound descriptor is also accepted::
|
||||
|
||||
query(MyClass).options(
|
||||
undefer(MyClass.attribute_one),
|
||||
undefer(MyClass.attribute_two))
|
||||
undefer(MyClass.attribute_one),
|
||||
undefer(MyClass.attribute_two))
|
||||
|
||||
A "path" can be specified onto a related or collection object using a
|
||||
dotted name. The :func:`.orm.undefer` option will be applied to that
|
||||
object when loaded::
|
||||
|
||||
query(MyClass).options(
|
||||
undefer("related.attribute_one"),
|
||||
undefer("related.attribute_two"))
|
||||
undefer("related.attribute_one"),
|
||||
undefer("related.attribute_two"))
|
||||
|
||||
To specify a path via class, send multiple arguments::
|
||||
|
||||
query(MyClass).options(
|
||||
undefer(MyClass.related, MyOtherClass.attribute_one),
|
||||
undefer(MyClass.related, MyOtherClass.attribute_two))
|
||||
undefer(MyClass.related, MyOtherClass.attribute_one),
|
||||
undefer(MyClass.related, MyOtherClass.attribute_two))
|
||||
|
||||
See also:
|
||||
|
||||
@@ -1671,9 +1700,10 @@ def undefer(*key):
|
||||
"""
|
||||
return strategies.DeferredOption(key, defer=False)
|
||||
|
||||
|
||||
def undefer_group(name):
|
||||
"""Return a :class:`.MapperOption` that will convert the given group of deferred
|
||||
column properties into a non-deferred (regular column) load.
|
||||
"""Return a :class:`.MapperOption` that will convert the given group of
|
||||
deferred column properties into a non-deferred (regular column) load.
|
||||
|
||||
Used with :meth:`.Query.options`.
|
||||
|
||||
|
||||
@@ -85,8 +85,8 @@ canonical=16
|
||||
)
|
||||
|
||||
LOAD_AGAINST_COMMITTED = util.symbol("LOAD_AGAINST_COMMITTED",
|
||||
"""callables should use committed values as primary/foreign keys during a load""",
|
||||
canonical=32
|
||||
"""callables should use committed values as primary/foreign keys during a load
|
||||
""", canonical=32
|
||||
)
|
||||
|
||||
# pre-packaged sets of flags used as inputs
|
||||
@@ -229,6 +229,7 @@ class QueryableAttribute(interfaces._MappedAttribute,
|
||||
|
||||
inspection._self_inspects(QueryableAttribute)
|
||||
|
||||
|
||||
class InstrumentedAttribute(QueryableAttribute):
|
||||
"""Class bound instrumented attribute which adds descriptor methods."""
|
||||
|
||||
@@ -247,7 +248,8 @@ class InstrumentedAttribute(QueryableAttribute):
|
||||
if self._supports_population and self.key in dict_:
|
||||
return dict_[self.key]
|
||||
else:
|
||||
return self.impl.get(instance_state(instance),dict_)
|
||||
return self.impl.get(instance_state(instance), dict_)
|
||||
|
||||
|
||||
def create_proxied_attribute(descriptor):
|
||||
"""Create an QueryableAttribute / user descriptor hybrid.
|
||||
@@ -291,8 +293,10 @@ def create_proxied_attribute(descriptor):
|
||||
return self._comparator
|
||||
|
||||
def adapted(self, adapter):
|
||||
"""Proxy adapted() for the use case of AliasedClass calling adapted."""
|
||||
"""Proxy adapted() for the use case of AliasedClass calling
|
||||
adapted.
|
||||
|
||||
"""
|
||||
return self.__class__(self.class_, self.key, self.descriptor,
|
||||
self._comparator,
|
||||
adapter)
|
||||
@@ -325,7 +329,6 @@ def create_proxied_attribute(descriptor):
|
||||
attribute)
|
||||
)
|
||||
|
||||
|
||||
Proxy.__name__ = type(descriptor).__name__ + 'Proxy'
|
||||
|
||||
util.monkeypatch_proxied_specials(Proxy, type(descriptor),
|
||||
@@ -333,6 +336,7 @@ def create_proxied_attribute(descriptor):
|
||||
from_instance=descriptor)
|
||||
return Proxy
|
||||
|
||||
|
||||
class AttributeImpl(object):
|
||||
"""internal implementation for instrumented attributes."""
|
||||
|
||||
@@ -417,7 +421,6 @@ class AttributeImpl(object):
|
||||
|
||||
active_history = property(_get_active_history, _set_active_history)
|
||||
|
||||
|
||||
def hasparent(self, state, optimistic=False):
|
||||
"""Return the boolean value of a `hasparent` flag attached to
|
||||
the given state.
|
||||
@@ -434,7 +437,8 @@ class AttributeImpl(object):
|
||||
will also not have a `hasparent` flag.
|
||||
|
||||
"""
|
||||
assert self.trackparent, "This AttributeImpl is not configured to track parents."
|
||||
msg = "This AttributeImpl is not configured to track parents."
|
||||
assert self.trackparent, msg
|
||||
|
||||
return state.parents.get(id(self.parent_token), optimistic) \
|
||||
is not False
|
||||
@@ -445,7 +449,8 @@ class AttributeImpl(object):
|
||||
attribute represented by this ``InstrumentedAttribute``.
|
||||
|
||||
"""
|
||||
assert self.trackparent, "This AttributeImpl is not configured to track parents."
|
||||
msg = "This AttributeImpl is not configured to track parents."
|
||||
assert self.trackparent, msg
|
||||
|
||||
id_ = id(self.parent_token)
|
||||
if value:
|
||||
@@ -472,7 +477,6 @@ class AttributeImpl(object):
|
||||
|
||||
state.parents[id_] = False
|
||||
|
||||
|
||||
def set_callable(self, state, callable_):
|
||||
"""Set a callable function for this attribute on the given object.
|
||||
|
||||
@@ -596,6 +600,7 @@ class AttributeImpl(object):
|
||||
state._commit(dict_, [self.key])
|
||||
return value
|
||||
|
||||
|
||||
class ScalarAttributeImpl(AttributeImpl):
|
||||
"""represents a scalar value-holding InstrumentedAttribute."""
|
||||
|
||||
@@ -651,8 +656,6 @@ class ScalarAttributeImpl(AttributeImpl):
|
||||
self.property.columns[0].type
|
||||
|
||||
|
||||
|
||||
|
||||
class ScalarObjectAttributeImpl(ScalarAttributeImpl):
|
||||
"""represents a scalar-holding InstrumentedAttribute,
|
||||
where the target object is also instrumented.
|
||||
@@ -834,7 +837,6 @@ class CollectionAttributeImpl(AttributeImpl):
|
||||
|
||||
return [(instance_state(o), o) for o in current]
|
||||
|
||||
|
||||
def fire_append_event(self, state, dict_, value, initiator):
|
||||
for fn in self.dispatch.append:
|
||||
value = fn(state, value, initiator or self)
|
||||
@@ -1011,6 +1013,7 @@ class CollectionAttributeImpl(AttributeImpl):
|
||||
|
||||
return getattr(user_data, '_sa_adapter')
|
||||
|
||||
|
||||
def backref_listeners(attribute, key, uselist):
|
||||
"""Apply listeners to synchronize a two-way relationship."""
|
||||
|
||||
@@ -1110,6 +1113,7 @@ History = util.namedtuple("History", [
|
||||
"added", "unchanged", "deleted"
|
||||
])
|
||||
|
||||
|
||||
class History(History):
|
||||
"""A 3-tuple of added, unchanged and deleted values,
|
||||
representing the changes which have occurred on an instrumented
|
||||
@@ -1273,6 +1277,7 @@ class History(History):
|
||||
|
||||
HISTORY_BLANK = History(None, None, None)
|
||||
|
||||
|
||||
def get_history(obj, key, passive=PASSIVE_OFF):
|
||||
"""Return a :class:`.History` record for the given object
|
||||
and attribute key.
|
||||
@@ -1300,6 +1305,7 @@ def get_history(obj, key, passive=PASSIVE_OFF):
|
||||
|
||||
return get_state_history(instance_state(obj), key, passive)
|
||||
|
||||
|
||||
def get_state_history(state, key, passive=PASSIVE_OFF):
|
||||
return state.get_history(key, passive)
|
||||
|
||||
@@ -1310,6 +1316,7 @@ def has_parent(cls, obj, key, optimistic=False):
|
||||
state = instance_state(obj)
|
||||
return manager.has_parent(state, key, optimistic)
|
||||
|
||||
|
||||
def register_attribute(class_, key, **kw):
|
||||
comparator = kw.pop('comparator', None)
|
||||
parententity = kw.pop('parententity', None)
|
||||
@@ -1319,6 +1326,7 @@ def register_attribute(class_, key, **kw):
|
||||
register_attribute_impl(class_, key, **kw)
|
||||
return desc
|
||||
|
||||
|
||||
def register_attribute_impl(class_, key,
|
||||
uselist=False, callable_=None,
|
||||
useobject=False,
|
||||
@@ -1341,7 +1349,7 @@ def register_attribute_impl(class_, key,
|
||||
typecallable=typecallable, **kw)
|
||||
elif useobject:
|
||||
impl = ScalarObjectAttributeImpl(class_, key, callable_,
|
||||
dispatch,**kw)
|
||||
dispatch, **kw)
|
||||
else:
|
||||
impl = ScalarAttributeImpl(class_, key, callable_, dispatch, **kw)
|
||||
|
||||
@@ -1353,6 +1361,7 @@ def register_attribute_impl(class_, key,
|
||||
manager.post_configure_attribute(key)
|
||||
return manager[key]
|
||||
|
||||
|
||||
def register_descriptor(class_, key, comparator=None,
|
||||
parententity=None, doc=None):
|
||||
manager = manager_of_class(class_)
|
||||
@@ -1365,9 +1374,11 @@ def register_descriptor(class_, key, comparator=None,
|
||||
manager.instrument_attribute(key, descriptor)
|
||||
return descriptor
|
||||
|
||||
|
||||
def unregister_attribute(class_, key):
|
||||
manager_of_class(class_).uninstrument_attribute(key)
|
||||
|
||||
|
||||
def init_collection(obj, key):
|
||||
"""Initialize a collection attribute and return the collection adapter.
|
||||
|
||||
@@ -1390,6 +1401,7 @@ def init_collection(obj, key):
|
||||
dict_ = state.dict
|
||||
return init_state_collection(state, dict_, key)
|
||||
|
||||
|
||||
def init_state_collection(state, dict_, key):
|
||||
"""Initialize a collection attribute and return the collection adapter."""
|
||||
|
||||
@@ -1397,6 +1409,7 @@ def init_state_collection(state, dict_, key):
|
||||
user_data = attr.initialize(state, dict_)
|
||||
return attr.get_collection(state, dict_, user_data)
|
||||
|
||||
|
||||
def set_committed_value(instance, key, value):
|
||||
"""Set the value of an attribute with no history events.
|
||||
|
||||
@@ -1415,6 +1428,7 @@ def set_committed_value(instance, key, value):
|
||||
state, dict_ = instance_state(instance), instance_dict(instance)
|
||||
state.manager[key].impl.set_committed_value(state, dict_, value)
|
||||
|
||||
|
||||
def set_attribute(instance, key, value):
|
||||
"""Set the value of an attribute, firing history events.
|
||||
|
||||
@@ -1428,6 +1442,7 @@ def set_attribute(instance, key, value):
|
||||
state, dict_ = instance_state(instance), instance_dict(instance)
|
||||
state.manager[key].impl.set(state, dict_, value, None)
|
||||
|
||||
|
||||
def get_attribute(instance, key):
|
||||
"""Get the value of an attribute, firing any callables required.
|
||||
|
||||
@@ -1441,6 +1456,7 @@ def get_attribute(instance, key):
|
||||
state, dict_ = instance_state(instance), instance_dict(instance)
|
||||
return state.manager[key].impl.get(state, dict_)
|
||||
|
||||
|
||||
def del_attribute(instance, key):
|
||||
"""Delete the value of an attribute, firing history events.
|
||||
|
||||
@@ -1454,6 +1470,7 @@ def del_attribute(instance, key):
|
||||
state, dict_ = instance_state(instance), instance_dict(instance)
|
||||
state.manager[key].impl.delete(state, dict_)
|
||||
|
||||
|
||||
def flag_modified(instance, key):
|
||||
"""Mark an attribute on an instance as 'modified'.
|
||||
|
||||
@@ -1464,4 +1481,3 @@ def flag_modified(instance, key):
|
||||
state, dict_ = instance_state(instance), instance_dict(instance)
|
||||
impl = state.manager[key].impl
|
||||
state._modified_event(dict_, impl, NO_VALUE)
|
||||
|
||||
|
||||
@@ -153,6 +153,7 @@ class _PlainColumnGetter(object):
|
||||
else:
|
||||
return key[0]
|
||||
|
||||
|
||||
class _SerializableColumnGetter(object):
|
||||
"""Column-based getter used in version 0.7.6 only.
|
||||
|
||||
@@ -178,6 +179,7 @@ class _SerializableColumnGetter(object):
|
||||
else:
|
||||
return key[0]
|
||||
|
||||
|
||||
class _SerializableColumnGetterV2(_PlainColumnGetter):
|
||||
"""Updated serializable getter which deals with
|
||||
multi-table mapped classes.
|
||||
@@ -239,6 +241,7 @@ def column_mapped_collection(mapping_spec):
|
||||
keyfunc = _PlainColumnGetter(cols)
|
||||
return lambda: MappedCollection(keyfunc)
|
||||
|
||||
|
||||
class _SerializableAttrGetter(object):
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
@@ -250,6 +253,7 @@ class _SerializableAttrGetter(object):
|
||||
def __reduce__(self):
|
||||
return _SerializableAttrGetter, (self.name, )
|
||||
|
||||
|
||||
def attribute_mapped_collection(attr_name):
|
||||
"""A dictionary-based collection type with attribute-based keying.
|
||||
|
||||
@@ -282,6 +286,7 @@ def mapped_collection(keyfunc):
|
||||
"""
|
||||
return lambda: MappedCollection(keyfunc)
|
||||
|
||||
|
||||
class collection(object):
|
||||
"""Decorators for entity collection classes.
|
||||
|
||||
@@ -551,6 +556,7 @@ def collection_adapter(collection):
|
||||
|
||||
return getattr(collection, '_sa_adapter', None)
|
||||
|
||||
|
||||
def collection_iter(collection):
|
||||
"""Iterate over an object supporting the @iterator or __iter__ protocols.
|
||||
|
||||
@@ -803,6 +809,7 @@ def bulk_replace(values, existing_adapter, new_adapter):
|
||||
for member in removals:
|
||||
existing_adapter.remove_with_event(member)
|
||||
|
||||
|
||||
def prepare_instrumentation(factory):
|
||||
"""Prepare a callable for future use as a collection class factory.
|
||||
|
||||
@@ -837,6 +844,7 @@ def prepare_instrumentation(factory):
|
||||
|
||||
return factory
|
||||
|
||||
|
||||
def __converting_factory(original_factory):
|
||||
"""Convert the type returned by collection factories on the fly.
|
||||
|
||||
@@ -864,6 +872,7 @@ def __converting_factory(original_factory):
|
||||
pass
|
||||
return wrapper
|
||||
|
||||
|
||||
def _instrument_class(cls):
|
||||
"""Modify methods in a class and install instrumentation."""
|
||||
|
||||
@@ -973,6 +982,7 @@ def _instrument_class(cls):
|
||||
|
||||
setattr(cls, '_sa_instrumented', id(cls))
|
||||
|
||||
|
||||
def _instrument_membership_mutator(method, before, argument, after):
|
||||
"""Route method args and/or return value through the collection adapter."""
|
||||
# This isn't smart enough to handle @adds(1) for 'def fn(self, (a, b))'
|
||||
@@ -1029,6 +1039,7 @@ def _instrument_membership_mutator(method, before, argument, after):
|
||||
pass
|
||||
return wrapper
|
||||
|
||||
|
||||
def __set(collection, item, _sa_initiator=None):
|
||||
"""Run set events, may eventually be inlined into decorators."""
|
||||
|
||||
@@ -1038,6 +1049,7 @@ def __set(collection, item, _sa_initiator=None):
|
||||
item = getattr(executor, 'fire_append_event')(item, _sa_initiator)
|
||||
return item
|
||||
|
||||
|
||||
def __del(collection, item, _sa_initiator=None):
|
||||
"""Run del events, may eventually be inlined into decorators."""
|
||||
if _sa_initiator is not False:
|
||||
@@ -1045,12 +1057,14 @@ def __del(collection, item, _sa_initiator=None):
|
||||
if executor:
|
||||
getattr(executor, 'fire_remove_event')(item, _sa_initiator)
|
||||
|
||||
|
||||
def __before_delete(collection, _sa_initiator=None):
|
||||
"""Special method to run 'commit existing value' methods"""
|
||||
executor = getattr(collection, '_sa_adapter', None)
|
||||
if executor:
|
||||
getattr(executor, 'fire_pre_remove_event')(_sa_initiator)
|
||||
|
||||
|
||||
def _list_decorators():
|
||||
"""Tailored instrumentation wrappers for any list-like class."""
|
||||
|
||||
@@ -1188,6 +1202,7 @@ def _list_decorators():
|
||||
l.pop('_tidy')
|
||||
return l
|
||||
|
||||
|
||||
def _dict_decorators():
|
||||
"""Tailored instrumentation wrappers for any dict-like mapping class."""
|
||||
|
||||
@@ -1281,11 +1296,13 @@ else:
|
||||
import sets
|
||||
_set_binop_bases = (set, frozenset, sets.BaseSet)
|
||||
|
||||
|
||||
def _set_binops_check_strict(self, obj):
|
||||
"""Allow only set, frozenset and self.__class__-derived
|
||||
objects in binops."""
|
||||
return isinstance(obj, _set_binop_bases + (self.__class__,))
|
||||
|
||||
|
||||
def _set_binops_check_loose(self, obj):
|
||||
"""Allow anything set-like to participate in set binops."""
|
||||
return (isinstance(obj, _set_binop_bases + (self.__class__,)) or
|
||||
@@ -1448,6 +1465,7 @@ class InstrumentedList(list):
|
||||
'remover': 'remove',
|
||||
'iterator': '__iter__', }
|
||||
|
||||
|
||||
class InstrumentedSet(set):
|
||||
"""An instrumented version of the built-in set."""
|
||||
|
||||
@@ -1456,6 +1474,7 @@ class InstrumentedSet(set):
|
||||
'remover': 'remove',
|
||||
'iterator': '__iter__', }
|
||||
|
||||
|
||||
class InstrumentedDict(dict):
|
||||
"""An instrumented version of the built-in dict."""
|
||||
|
||||
@@ -1494,6 +1513,7 @@ __interfaces = {
|
||||
None: {}
|
||||
}
|
||||
|
||||
|
||||
class MappedCollection(dict):
|
||||
"""A basic dictionary-based collection class.
|
||||
|
||||
@@ -1577,4 +1597,3 @@ class MappedCollection(dict):
|
||||
_instrument_class(MappedCollection)
|
||||
_instrument_class(InstrumentedList)
|
||||
_instrument_class(InstrumentedSet)
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ from . import attributes, exc, sync, unitofwork, \
|
||||
util as mapperutil
|
||||
from .interfaces import ONETOMANY, MANYTOONE, MANYTOMANY
|
||||
|
||||
|
||||
class DependencyProcessor(object):
|
||||
def __init__(self, prop):
|
||||
self.prop = prop
|
||||
@@ -63,7 +64,6 @@ class DependencyProcessor(object):
|
||||
"""
|
||||
uow.register_preprocessor(self, True)
|
||||
|
||||
|
||||
def per_property_flush_actions(self, uow):
|
||||
after_save = unitofwork.ProcessAll(uow, self, False, True)
|
||||
before_delete = unitofwork.ProcessAll(uow, self, True, True)
|
||||
@@ -95,7 +95,6 @@ class DependencyProcessor(object):
|
||||
before_delete
|
||||
)
|
||||
|
||||
|
||||
def per_state_flush_actions(self, uow, states, isdelete):
|
||||
"""establish actions and dependencies related to a flush.
|
||||
|
||||
@@ -159,7 +158,8 @@ class DependencyProcessor(object):
|
||||
# detect if there's anything changed or loaded
|
||||
# by a preprocessor on this state/attribute. if not,
|
||||
# we should be able to skip it entirely.
|
||||
sum_ = state.manager[self.key].impl.get_all_pending(state, state.dict)
|
||||
sum_ = state.manager[self.key].impl.get_all_pending(
|
||||
state, state.dict)
|
||||
|
||||
if not sum_:
|
||||
continue
|
||||
@@ -210,7 +210,6 @@ class DependencyProcessor(object):
|
||||
after_save, before_delete,
|
||||
isdelete, childisdelete)
|
||||
|
||||
|
||||
def presort_deletes(self, uowcommit, states):
|
||||
return False
|
||||
|
||||
@@ -314,6 +313,7 @@ class DependencyProcessor(object):
|
||||
def __repr__(self):
|
||||
return "%s(%s)" % (self.__class__.__name__, self.prop)
|
||||
|
||||
|
||||
class OneToManyDP(DependencyProcessor):
|
||||
|
||||
def per_property_dependencies(self, uow, parent_saves,
|
||||
@@ -437,8 +437,6 @@ class OneToManyDP(DependencyProcessor):
|
||||
uowcommit.register_object(child,
|
||||
operation="delete", prop=self.prop)
|
||||
|
||||
|
||||
|
||||
def presort_saves(self, uowcommit, states):
|
||||
children_added = uowcommit.memo(('children_added', self), set)
|
||||
|
||||
@@ -581,6 +579,7 @@ class OneToManyDP(DependencyProcessor):
|
||||
self.parent,
|
||||
self.prop.synchronize_pairs)
|
||||
|
||||
|
||||
class ManyToOneDP(DependencyProcessor):
|
||||
def __init__(self, prop):
|
||||
DependencyProcessor.__init__(self, prop)
|
||||
@@ -694,8 +693,8 @@ class ManyToOneDP(DependencyProcessor):
|
||||
continue
|
||||
uowcommit.register_object(child, isdelete=True,
|
||||
operation="delete", prop=self.prop)
|
||||
for c, m, st_, dct_ in self.mapper.cascade_iterator(
|
||||
'delete', child):
|
||||
t = self.mapper.cascade_iterator('delete', child)
|
||||
for c, m, st_, dct_ in t:
|
||||
uowcommit.register_object(
|
||||
st_, isdelete=True)
|
||||
|
||||
@@ -713,11 +712,9 @@ class ManyToOneDP(DependencyProcessor):
|
||||
uowcommit.register_object(child, isdelete=True,
|
||||
operation="delete", prop=self.prop)
|
||||
|
||||
for c, m, st_, dct_ in self.mapper.cascade_iterator(
|
||||
'delete', child):
|
||||
uowcommit.register_object(
|
||||
st_,
|
||||
isdelete=True)
|
||||
t = self.mapper.cascade_iterator('delete', child)
|
||||
for c, m, st_, dct_ in t:
|
||||
uowcommit.register_object(st_, isdelete=True)
|
||||
|
||||
def process_deletes(self, uowcommit, states):
|
||||
if self.post_update and \
|
||||
@@ -776,6 +773,7 @@ class ManyToOneDP(DependencyProcessor):
|
||||
uowcommit,
|
||||
False)
|
||||
|
||||
|
||||
class DetectKeySwitch(DependencyProcessor):
|
||||
"""For many-to-one relationships with no one-to-many backref,
|
||||
searches for parents through the unit of work when a primary
|
||||
@@ -1100,11 +1098,11 @@ class ManyToManyDP(DependencyProcessor):
|
||||
if result.supports_sane_multi_rowcount() and \
|
||||
result.rowcount != len(secondary_delete):
|
||||
raise exc.StaleDataError(
|
||||
"DELETE statement on table '%s' expected to delete %d row(s); "
|
||||
"Only %d were matched." %
|
||||
(self.secondary.description, len(secondary_delete),
|
||||
result.rowcount)
|
||||
)
|
||||
"DELETE statement on table '%s' expected to delete "
|
||||
"%d row(s); Only %d were matched." %
|
||||
(self.secondary.description, len(secondary_delete),
|
||||
result.rowcount)
|
||||
)
|
||||
|
||||
if secondary_update:
|
||||
associationrow = secondary_update[0]
|
||||
@@ -1117,11 +1115,11 @@ class ManyToManyDP(DependencyProcessor):
|
||||
if result.supports_sane_multi_rowcount() and \
|
||||
result.rowcount != len(secondary_update):
|
||||
raise exc.StaleDataError(
|
||||
"UPDATE statement on table '%s' expected to update %d row(s); "
|
||||
"Only %d were matched." %
|
||||
(self.secondary.description, len(secondary_update),
|
||||
result.rowcount)
|
||||
)
|
||||
"UPDATE statement on table '%s' expected to update "
|
||||
"%d row(s); Only %d were matched." %
|
||||
(self.secondary.description, len(secondary_update),
|
||||
result.rowcount)
|
||||
)
|
||||
|
||||
if secondary_insert:
|
||||
statement = self.secondary.insert()
|
||||
@@ -1157,8 +1155,7 @@ class ManyToManyDP(DependencyProcessor):
|
||||
self.prop.synchronize_pairs)
|
||||
|
||||
_direction_to_processor = {
|
||||
ONETOMANY : OneToManyDP,
|
||||
ONETOMANY: OneToManyDP,
|
||||
MANYTOONE: ManyToOneDP,
|
||||
MANYTOMANY : ManyToManyDP,
|
||||
MANYTOMANY: ManyToManyDP,
|
||||
}
|
||||
|
||||
|
||||
@@ -116,7 +116,6 @@ class MapperExtension(object):
|
||||
event.listen(self, "%s" % meth, ls_meth,
|
||||
raw=False, retval=True, propagate=True)
|
||||
|
||||
|
||||
def instrument_class(self, mapper, class_):
|
||||
"""Receive a class when the mapper is first constructed, and has
|
||||
applied instrumentation to the mapped class.
|
||||
@@ -374,6 +373,7 @@ class MapperExtension(object):
|
||||
|
||||
return EXT_CONTINUE
|
||||
|
||||
|
||||
class SessionExtension(object):
|
||||
|
||||
"""Base implementation for :class:`.Session` event hooks.
|
||||
@@ -439,7 +439,7 @@ class SessionExtension(object):
|
||||
Note that this may not be per-flush if a longer running
|
||||
transaction is ongoing."""
|
||||
|
||||
def before_flush( self, session, flush_context, instances):
|
||||
def before_flush(self, session, flush_context, instances):
|
||||
"""Execute before flush process has started.
|
||||
|
||||
`instances` is an optional list of objects which were passed to
|
||||
@@ -462,7 +462,7 @@ class SessionExtension(object):
|
||||
occurred, depending on whether or not the flush started its own
|
||||
transaction or participated in a larger transaction. """
|
||||
|
||||
def after_begin( self, session, transaction, connection):
|
||||
def after_begin(self, session, transaction, connection):
|
||||
"""Execute after a transaction is begun on a connection
|
||||
|
||||
`transaction` is the SessionTransaction. This method is called
|
||||
@@ -473,7 +473,7 @@ class SessionExtension(object):
|
||||
|
||||
This is called after an add, delete or merge. """
|
||||
|
||||
def after_bulk_update( self, session, query, query_context, result):
|
||||
def after_bulk_update(self, session, query, query_context, result):
|
||||
"""Execute after a bulk update operation to the session.
|
||||
|
||||
This is called after a session.query(...).update()
|
||||
@@ -483,7 +483,7 @@ class SessionExtension(object):
|
||||
`result` is the result object returned from the bulk operation.
|
||||
"""
|
||||
|
||||
def after_bulk_delete( self, session, query, query_context, result):
|
||||
def after_bulk_delete(self, session, query, query_context, result):
|
||||
"""Execute after a bulk delete operation to the session.
|
||||
|
||||
This is called after a session.query(...).delete()
|
||||
@@ -586,5 +586,3 @@ class AttributeExtension(object):
|
||||
|
||||
"""
|
||||
return value
|
||||
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ from .. import util, sql, exc as sa_exc, event, schema
|
||||
from ..sql import expression
|
||||
properties = util.importlater('sqlalchemy.orm', 'properties')
|
||||
|
||||
|
||||
class DescriptorProperty(MapperProperty):
|
||||
""":class:`.MapperProperty` which proxies access to a
|
||||
user-defined descriptor."""
|
||||
@@ -47,8 +48,10 @@ class DescriptorProperty(MapperProperty):
|
||||
if self.descriptor is None:
|
||||
def fset(obj, value):
|
||||
setattr(obj, self.name, value)
|
||||
|
||||
def fdel(obj):
|
||||
delattr(obj, self.name)
|
||||
|
||||
def fget(obj):
|
||||
return getattr(obj, self.name)
|
||||
|
||||
@@ -124,7 +127,10 @@ class CompositeProperty(DescriptorProperty):
|
||||
# key not present. Iterate through related
|
||||
# attributes, retrieve their values. This
|
||||
# ensures they all load.
|
||||
values = [getattr(instance, key) for key in self._attribute_keys]
|
||||
values = [
|
||||
getattr(instance, key)
|
||||
for key in self._attribute_keys
|
||||
]
|
||||
|
||||
# current expected behavior here is that the composite is
|
||||
# created on access if the object is persistent or if
|
||||
@@ -239,12 +245,15 @@ class CompositeProperty(DescriptorProperty):
|
||||
state.dict.pop(self.key, None)
|
||||
|
||||
event.listen(self.parent, 'after_insert',
|
||||
insert_update_handler, raw=True)
|
||||
insert_update_handler, raw=True)
|
||||
event.listen(self.parent, 'after_update',
|
||||
insert_update_handler, raw=True)
|
||||
event.listen(self.parent, 'load', load_handler, raw=True, propagate=True)
|
||||
event.listen(self.parent, 'refresh', load_handler, raw=True, propagate=True)
|
||||
event.listen(self.parent, "expire", expire_handler, raw=True, propagate=True)
|
||||
insert_update_handler, raw=True)
|
||||
event.listen(self.parent, 'load',
|
||||
load_handler, raw=True, propagate=True)
|
||||
event.listen(self.parent, 'refresh',
|
||||
load_handler, raw=True, propagate=True)
|
||||
event.listen(self.parent, 'expire',
|
||||
expire_handler, raw=True, propagate=True)
|
||||
|
||||
# TODO: need a deserialize hook here
|
||||
|
||||
@@ -285,7 +294,7 @@ class CompositeProperty(DescriptorProperty):
|
||||
)
|
||||
else:
|
||||
return attributes.History(
|
||||
(),[self.composite_class(*added)], ()
|
||||
(), [self.composite_class(*added)], ()
|
||||
)
|
||||
|
||||
def _comparator_factory(self, mapper):
|
||||
@@ -317,7 +326,7 @@ class CompositeProperty(DescriptorProperty):
|
||||
if self.adapter:
|
||||
# TODO: test coverage for adapted composite comparison
|
||||
return expression.ClauseList(
|
||||
*[self.adapter(x) for x in self.prop._comparable_elements])
|
||||
*[self.adapter(x) for x in self.prop._comparable_elements])
|
||||
else:
|
||||
return expression.ClauseList(*self.prop._comparable_elements)
|
||||
|
||||
@@ -329,7 +338,9 @@ class CompositeProperty(DescriptorProperty):
|
||||
else:
|
||||
values = other.__composite_values__()
|
||||
return sql.and_(
|
||||
*[a==b for a, b in zip(self.prop._comparable_elements, values)])
|
||||
*[a == b
|
||||
for a, b in zip(self.prop._comparable_elements, values)]
|
||||
)
|
||||
|
||||
def __ne__(self, other):
|
||||
return sql.not_(self.__eq__(other))
|
||||
@@ -337,6 +348,7 @@ class CompositeProperty(DescriptorProperty):
|
||||
def __str__(self):
|
||||
return str(self.parent.class_.__name__) + "." + self.key
|
||||
|
||||
|
||||
class ConcreteInheritedProperty(DescriptorProperty):
|
||||
"""A 'do nothing' :class:`.MapperProperty` that disables
|
||||
an attribute on a concrete subclass that is only present
|
||||
@@ -374,8 +386,10 @@ class ConcreteInheritedProperty(DescriptorProperty):
|
||||
class NoninheritedConcreteProp(object):
|
||||
def __set__(s, obj, value):
|
||||
warn()
|
||||
|
||||
def __delete__(s, obj):
|
||||
warn()
|
||||
|
||||
def __get__(s, obj, owner):
|
||||
if obj is None:
|
||||
return self.descriptor
|
||||
@@ -440,6 +454,7 @@ class SynonymProperty(DescriptorProperty):
|
||||
|
||||
self.parent = parent
|
||||
|
||||
|
||||
class ComparableProperty(DescriptorProperty):
|
||||
"""Instruments a Python property for use in query expressions."""
|
||||
|
||||
|
||||
@@ -19,14 +19,15 @@ from . import (
|
||||
)
|
||||
from .query import Query
|
||||
|
||||
|
||||
class DynaLoader(strategies.AbstractRelationshipLoader):
|
||||
def init_class_attribute(self, mapper):
|
||||
self.is_class_level = True
|
||||
if not self.uselist:
|
||||
raise exc.InvalidRequestError(
|
||||
"On relationship %s, 'dynamic' loaders cannot be used with "
|
||||
"many-to-one/one-to-one relationships and/or "
|
||||
"uselist=False." % self.parent_property)
|
||||
"On relationship %s, 'dynamic' loaders cannot be used with "
|
||||
"many-to-one/one-to-one relationships and/or "
|
||||
"uselist=False." % self.parent_property)
|
||||
strategies._register_attribute(self,
|
||||
mapper,
|
||||
useobject=True,
|
||||
@@ -38,6 +39,7 @@ class DynaLoader(strategies.AbstractRelationshipLoader):
|
||||
|
||||
log.class_logger(DynaLoader)
|
||||
|
||||
|
||||
class DynamicAttributeImpl(attributes.AttributeImpl):
|
||||
uses_objects = True
|
||||
accepts_scalar_loader = False
|
||||
@@ -118,7 +120,6 @@ class DynamicAttributeImpl(attributes.AttributeImpl):
|
||||
return
|
||||
self._set_iterable(state, dict_, value)
|
||||
|
||||
|
||||
def _set_iterable(self, state, dict_, iterable, adapter=None):
|
||||
collection_history = self._modified_event(state, dict_)
|
||||
new_values = list(iterable)
|
||||
@@ -144,7 +145,8 @@ class DynamicAttributeImpl(attributes.AttributeImpl):
|
||||
c.deleted_items)
|
||||
|
||||
def get_all_pending(self, state, dict_):
|
||||
c = self._get_collection_history(state, attributes.PASSIVE_NO_INITIALIZE)
|
||||
c = self._get_collection_history(
|
||||
state, attributes.PASSIVE_NO_INITIALIZE)
|
||||
return [
|
||||
(attributes.instance_state(x), x)
|
||||
for x in
|
||||
@@ -174,6 +176,7 @@ class DynamicAttributeImpl(attributes.AttributeImpl):
|
||||
if initiator is not self:
|
||||
self.fire_remove_event(state, dict_, value, initiator)
|
||||
|
||||
|
||||
class DynCollectionAdapter(object):
|
||||
"""the dynamic analogue to orm.collections.CollectionAdapter"""
|
||||
|
||||
@@ -197,6 +200,7 @@ class DynCollectionAdapter(object):
|
||||
def remove_without_event(self, item):
|
||||
pass
|
||||
|
||||
|
||||
class AppenderMixin(object):
|
||||
query_class = None
|
||||
|
||||
@@ -228,7 +232,7 @@ class AppenderMixin(object):
|
||||
|
||||
def session(self):
|
||||
return self.__session()
|
||||
session = property(session, lambda s, x:None)
|
||||
session = property(session, lambda s, x: None)
|
||||
|
||||
def __iter__(self):
|
||||
sess = self.__session()
|
||||
@@ -302,6 +306,7 @@ def mixin_user_query(cls):
|
||||
name = 'Appender' + cls.__name__
|
||||
return type(name, (AppenderMixin, cls), {'query_class': cls})
|
||||
|
||||
|
||||
class CollectionHistory(object):
|
||||
"""Overrides AttributeHistory to receive append/remove events directly."""
|
||||
|
||||
@@ -318,4 +323,3 @@ class CollectionHistory(object):
|
||||
self.deleted_items = []
|
||||
self.added_items = []
|
||||
self.unchanged_items = []
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
import operator
|
||||
from ..sql import operators
|
||||
|
||||
|
||||
class UnevaluatableError(Exception):
|
||||
pass
|
||||
|
||||
@@ -24,6 +25,7 @@ _notimplemented_ops = set(getattr(operators, op)
|
||||
'notilike_op', 'between_op', 'in_op',
|
||||
'notin_op', 'endswith_op', 'concat_op'))
|
||||
|
||||
|
||||
class EvaluatorCompiler(object):
|
||||
def process(self, clause):
|
||||
meth = getattr(self, "visit_%s" % clause.__visit_name__, None)
|
||||
@@ -77,7 +79,7 @@ class EvaluatorCompiler(object):
|
||||
return evaluate
|
||||
|
||||
def visit_binary(self, clause):
|
||||
eval_left,eval_right = map(self.process,
|
||||
eval_left, eval_right = map(self.process,
|
||||
[clause.left, clause.right])
|
||||
operator = clause.operator
|
||||
if operator is operators.is_:
|
||||
|
||||
@@ -94,13 +94,13 @@ class InstrumentationEvents(event.Events):
|
||||
|
||||
"""
|
||||
|
||||
|
||||
def attribute_instrument(self, cls, key, inst):
|
||||
"""Called when an attribute is instrumented."""
|
||||
|
||||
|
||||
class _InstrumentationEventsHold(object):
|
||||
"""temporary marker object used to transfer from _accept_with() to _listen()
|
||||
on the InstrumentationEvents class.
|
||||
"""temporary marker object used to transfer from _accept_with() to
|
||||
_listen() on the InstrumentationEvents class.
|
||||
|
||||
"""
|
||||
def __init__(self, class_):
|
||||
@@ -174,6 +174,7 @@ class InstanceEvents(event.Events):
|
||||
def _listen(cls, target, identifier, fn, raw=False, propagate=False):
|
||||
if not raw:
|
||||
orig_fn = fn
|
||||
|
||||
def wrap(state, *arg, **kw):
|
||||
return orig_fn(state.obj(), *arg, **kw)
|
||||
fn = wrap
|
||||
@@ -185,7 +186,8 @@ class InstanceEvents(event.Events):
|
||||
|
||||
@classmethod
|
||||
def _remove(cls, identifier, target, fn):
|
||||
raise NotImplementedError("Removal of instance events not yet implemented")
|
||||
msg = "Removal of instance events not yet implemented"
|
||||
raise NotImplementedError(msg)
|
||||
|
||||
@classmethod
|
||||
def _clear(cls):
|
||||
@@ -314,6 +316,7 @@ class InstanceEvents(event.Events):
|
||||
|
||||
"""
|
||||
|
||||
|
||||
class _EventsHold(object):
|
||||
"""Hold onto listeners against unmapped, uninstrumented classes.
|
||||
|
||||
@@ -361,6 +364,7 @@ class _EventsHold(object):
|
||||
subject.dispatch._listen(subject, ident,
|
||||
fn, raw, propagate)
|
||||
|
||||
|
||||
class _InstanceEventsHold(_EventsHold):
|
||||
all_holds = weakref.WeakKeyDictionary()
|
||||
|
||||
@@ -389,7 +393,8 @@ class MapperEvents(event.Events):
|
||||
|
||||
# associate the listener function with SomeMappedClass,
|
||||
# to execute during the "before_insert" hook
|
||||
event.listen(SomeMappedClass, 'before_insert', my_before_insert_listener)
|
||||
event.listen(
|
||||
SomeMappedClass, 'before_insert', my_before_insert_listener)
|
||||
|
||||
Available targets include mapped classes, instances of
|
||||
:class:`.Mapper` (i.e. returned by :func:`.mapper`,
|
||||
@@ -469,11 +474,13 @@ class MapperEvents(event.Events):
|
||||
if not raw:
|
||||
meth = getattr(cls, identifier)
|
||||
try:
|
||||
target_index = inspect.getargspec(meth)[0].index('target') - 1
|
||||
target_index = \
|
||||
inspect.getargspec(meth)[0].index('target') - 1
|
||||
except ValueError:
|
||||
target_index = None
|
||||
|
||||
wrapped_fn = fn
|
||||
|
||||
def wrap(*arg, **kw):
|
||||
if not raw and target_index is not None:
|
||||
arg = list(arg)
|
||||
@@ -516,9 +523,9 @@ class MapperEvents(event.Events):
|
||||
"""Called when the mapper for the class is fully configured.
|
||||
|
||||
This event is the latest phase of mapper construction, and
|
||||
is invoked when the mapped classes are first used, so that relationships
|
||||
between mappers can be resolved. When the event is called,
|
||||
the mapper should be in its final state.
|
||||
is invoked when the mapped classes are first used, so that
|
||||
relationships between mappers can be resolved. When the event is
|
||||
called, the mapper should be in its final state.
|
||||
|
||||
While the configuration event normally occurs automatically,
|
||||
it can be forced to occur ahead of time, in the case where the event
|
||||
@@ -542,9 +549,9 @@ class MapperEvents(event.Events):
|
||||
|
||||
Theoretically this event is called once per
|
||||
application, but is actually called any time new mappers
|
||||
have been affected by a :func:`.orm.configure_mappers` call. If new mappings
|
||||
are constructed after existing ones have already been used,
|
||||
this event can be called again.
|
||||
have been affected by a :func:`.orm.configure_mappers`
|
||||
call. If new mappings are constructed after existing ones have
|
||||
already been used, this event can be called again.
|
||||
|
||||
"""
|
||||
|
||||
@@ -632,7 +639,6 @@ class MapperEvents(event.Events):
|
||||
|
||||
"""
|
||||
|
||||
|
||||
def populate_instance(self, mapper, context, row,
|
||||
target, **flags):
|
||||
"""Receive an instance before that instance has
|
||||
@@ -688,24 +694,26 @@ class MapperEvents(event.Events):
|
||||
.. warning::
|
||||
Mapper-level flush events are designed to operate **on attributes
|
||||
local to the immediate object being handled
|
||||
and via SQL operations with the given** :class:`.Connection` **only.**
|
||||
Handlers here should **not** make alterations to the state of
|
||||
the :class:`.Session` overall, and in general should not
|
||||
affect any :func:`.relationship` -mapped attributes, as
|
||||
session cascade rules will not function properly, nor is it
|
||||
always known if the related class has already been handled.
|
||||
Operations that **are not supported in mapper events** include:
|
||||
and via SQL operations with the given**
|
||||
:class:`.Connection` **only.** Handlers here should **not** make
|
||||
alterations to the state of the :class:`.Session` overall, and
|
||||
in general should not affect any :func:`.relationship` -mapped
|
||||
attributes, as session cascade rules will not function properly,
|
||||
nor is it always known if the related class has already been
|
||||
handled. Operations that **are not supported in mapper
|
||||
events** include:
|
||||
|
||||
* :meth:`.Session.add`
|
||||
* :meth:`.Session.delete`
|
||||
* Mapped collection append, add, remove, delete, discard, etc.
|
||||
* Mapped relationship attribute set/del events, i.e. ``someobject.related = someotherobject``
|
||||
* Mapped relationship attribute set/del events,
|
||||
i.e. ``someobject.related = someotherobject``
|
||||
|
||||
Operations which manipulate the state of the object
|
||||
relative to other objects are better handled:
|
||||
|
||||
* In the ``__init__()`` method of the mapped object itself, or another method
|
||||
designed to establish some particular state.
|
||||
* In the ``__init__()`` method of the mapped object itself, or
|
||||
another method designed to establish some particular state.
|
||||
* In a ``@validates`` handler, see :ref:`simple_validators`
|
||||
* Within the :meth:`.SessionEvents.before_flush` event.
|
||||
|
||||
@@ -744,24 +752,26 @@ class MapperEvents(event.Events):
|
||||
.. warning::
|
||||
Mapper-level flush events are designed to operate **on attributes
|
||||
local to the immediate object being handled
|
||||
and via SQL operations with the given** :class:`.Connection` **only.**
|
||||
Handlers here should **not** make alterations to the state of
|
||||
the :class:`.Session` overall, and in general should not
|
||||
affect any :func:`.relationship` -mapped attributes, as
|
||||
session cascade rules will not function properly, nor is it
|
||||
always known if the related class has already been handled.
|
||||
Operations that **are not supported in mapper events** include:
|
||||
and via SQL operations with the given**
|
||||
:class:`.Connection` **only.** Handlers here should **not** make
|
||||
alterations to the state of the :class:`.Session` overall, and in
|
||||
general should not affect any :func:`.relationship` -mapped
|
||||
attributes, as session cascade rules will not function properly,
|
||||
nor is it always known if the related class has already been
|
||||
handled. Operations that **are not supported in mapper
|
||||
events** include:
|
||||
|
||||
* :meth:`.Session.add`
|
||||
* :meth:`.Session.delete`
|
||||
* Mapped collection append, add, remove, delete, discard, etc.
|
||||
* Mapped relationship attribute set/del events, i.e. ``someobject.related = someotherobject``
|
||||
* Mapped relationship attribute set/del events,
|
||||
i.e. ``someobject.related = someotherobject``
|
||||
|
||||
Operations which manipulate the state of the object
|
||||
relative to other objects are better handled:
|
||||
|
||||
* In the ``__init__()`` method of the mapped object itself, or another method
|
||||
designed to establish some particular state.
|
||||
* In the ``__init__()`` method of the mapped object itself,
|
||||
or another method designed to establish some particular state.
|
||||
* In a ``@validates`` handler, see :ref:`simple_validators`
|
||||
* Within the :meth:`.SessionEvents.before_flush` event.
|
||||
|
||||
@@ -819,9 +829,9 @@ class MapperEvents(event.Events):
|
||||
.. warning::
|
||||
Mapper-level flush events are designed to operate **on attributes
|
||||
local to the immediate object being handled
|
||||
and via SQL operations with the given** :class:`.Connection` **only.**
|
||||
Handlers here should **not** make alterations to the state of
|
||||
the :class:`.Session` overall, and in general should not
|
||||
and via SQL operations with the given** :class:`.Connection`
|
||||
**only.** Handlers here should **not** make alterations to the
|
||||
state of the :class:`.Session` overall, and in general should not
|
||||
affect any :func:`.relationship` -mapped attributes, as
|
||||
session cascade rules will not function properly, nor is it
|
||||
always known if the related class has already been handled.
|
||||
@@ -830,13 +840,14 @@ class MapperEvents(event.Events):
|
||||
* :meth:`.Session.add`
|
||||
* :meth:`.Session.delete`
|
||||
* Mapped collection append, add, remove, delete, discard, etc.
|
||||
* Mapped relationship attribute set/del events, i.e. ``someobject.related = someotherobject``
|
||||
* Mapped relationship attribute set/del events,
|
||||
i.e. ``someobject.related = someotherobject``
|
||||
|
||||
Operations which manipulate the state of the object
|
||||
relative to other objects are better handled:
|
||||
|
||||
* In the ``__init__()`` method of the mapped object itself, or another method
|
||||
designed to establish some particular state.
|
||||
* In the ``__init__()`` method of the mapped object itself,
|
||||
or another method designed to establish some particular state.
|
||||
* In a ``@validates`` handler, see :ref:`simple_validators`
|
||||
* Within the :meth:`.SessionEvents.before_flush` event.
|
||||
|
||||
@@ -892,9 +903,9 @@ class MapperEvents(event.Events):
|
||||
.. warning::
|
||||
Mapper-level flush events are designed to operate **on attributes
|
||||
local to the immediate object being handled
|
||||
and via SQL operations with the given** :class:`.Connection` **only.**
|
||||
Handlers here should **not** make alterations to the state of
|
||||
the :class:`.Session` overall, and in general should not
|
||||
and via SQL operations with the given** :class:`.Connection`
|
||||
**only.** Handlers here should **not** make alterations to the
|
||||
state of the :class:`.Session` overall, and in general should not
|
||||
affect any :func:`.relationship` -mapped attributes, as
|
||||
session cascade rules will not function properly, nor is it
|
||||
always known if the related class has already been handled.
|
||||
@@ -903,13 +914,14 @@ class MapperEvents(event.Events):
|
||||
* :meth:`.Session.add`
|
||||
* :meth:`.Session.delete`
|
||||
* Mapped collection append, add, remove, delete, discard, etc.
|
||||
* Mapped relationship attribute set/del events, i.e. ``someobject.related = someotherobject``
|
||||
* Mapped relationship attribute set/del events,
|
||||
i.e. ``someobject.related = someotherobject``
|
||||
|
||||
Operations which manipulate the state of the object
|
||||
relative to other objects are better handled:
|
||||
|
||||
* In the ``__init__()`` method of the mapped object itself, or another method
|
||||
designed to establish some particular state.
|
||||
* In the ``__init__()`` method of the mapped object itself,
|
||||
or another method designed to establish some particular state.
|
||||
* In a ``@validates`` handler, see :ref:`simple_validators`
|
||||
* Within the :meth:`.SessionEvents.before_flush` event.
|
||||
|
||||
@@ -942,9 +954,9 @@ class MapperEvents(event.Events):
|
||||
.. warning::
|
||||
Mapper-level flush events are designed to operate **on attributes
|
||||
local to the immediate object being handled
|
||||
and via SQL operations with the given** :class:`.Connection` **only.**
|
||||
Handlers here should **not** make alterations to the state of
|
||||
the :class:`.Session` overall, and in general should not
|
||||
and via SQL operations with the given** :class:`.Connection`
|
||||
**only.** Handlers here should **not** make alterations to the
|
||||
state of the :class:`.Session` overall, and in general should not
|
||||
affect any :func:`.relationship` -mapped attributes, as
|
||||
session cascade rules will not function properly, nor is it
|
||||
always known if the related class has already been handled.
|
||||
@@ -953,13 +965,14 @@ class MapperEvents(event.Events):
|
||||
* :meth:`.Session.add`
|
||||
* :meth:`.Session.delete`
|
||||
* Mapped collection append, add, remove, delete, discard, etc.
|
||||
* Mapped relationship attribute set/del events, i.e. ``someobject.related = someotherobject``
|
||||
* Mapped relationship attribute set/del events,
|
||||
i.e. ``someobject.related = someotherobject``
|
||||
|
||||
Operations which manipulate the state of the object
|
||||
relative to other objects are better handled:
|
||||
|
||||
* In the ``__init__()`` method of the mapped object itself, or another method
|
||||
designed to establish some particular state.
|
||||
* In the ``__init__()`` method of the mapped object itself,
|
||||
or another method designed to establish some particular state.
|
||||
* In a ``@validates`` handler, see :ref:`simple_validators`
|
||||
* Within the :meth:`.SessionEvents.before_flush` event.
|
||||
|
||||
@@ -992,9 +1005,9 @@ class MapperEvents(event.Events):
|
||||
.. warning::
|
||||
Mapper-level flush events are designed to operate **on attributes
|
||||
local to the immediate object being handled
|
||||
and via SQL operations with the given** :class:`.Connection` **only.**
|
||||
Handlers here should **not** make alterations to the state of
|
||||
the :class:`.Session` overall, and in general should not
|
||||
and via SQL operations with the given** :class:`.Connection`
|
||||
**only.** Handlers here should **not** make alterations to the
|
||||
state of the :class:`.Session` overall, and in general should not
|
||||
affect any :func:`.relationship` -mapped attributes, as
|
||||
session cascade rules will not function properly, nor is it
|
||||
always known if the related class has already been handled.
|
||||
@@ -1003,13 +1016,14 @@ class MapperEvents(event.Events):
|
||||
* :meth:`.Session.add`
|
||||
* :meth:`.Session.delete`
|
||||
* Mapped collection append, add, remove, delete, discard, etc.
|
||||
* Mapped relationship attribute set/del events, i.e. ``someobject.related = someotherobject``
|
||||
* Mapped relationship attribute set/del events,
|
||||
i.e. ``someobject.related = someotherobject``
|
||||
|
||||
Operations which manipulate the state of the object
|
||||
relative to other objects are better handled:
|
||||
|
||||
* In the ``__init__()`` method of the mapped object itself, or another method
|
||||
designed to establish some particular state.
|
||||
* In the ``__init__()`` method of the mapped object itself,
|
||||
or another method designed to establish some particular state.
|
||||
* In a ``@validates`` handler, see :ref:`simple_validators`
|
||||
* Within the :meth:`.SessionEvents.before_flush` event.
|
||||
|
||||
@@ -1029,7 +1043,9 @@ class MapperEvents(event.Events):
|
||||
|
||||
@classmethod
|
||||
def _remove(cls, identifier, target, fn):
|
||||
raise NotImplementedError("Removal of mapper events not yet implemented")
|
||||
"Removal of mapper events not yet implemented"
|
||||
raise NotImplementedError(msg)
|
||||
|
||||
|
||||
class _MapperEventsHold(_EventsHold):
|
||||
all_holds = weakref.WeakKeyDictionary()
|
||||
@@ -1042,6 +1058,7 @@ class _MapperEventsHold(_EventsHold):
|
||||
|
||||
dispatch = event.dispatcher(HoldMapperEvents)
|
||||
|
||||
|
||||
class SessionEvents(event.Events):
|
||||
"""Define events specific to :class:`.Session` lifecycle.
|
||||
|
||||
@@ -1066,7 +1083,6 @@ class SessionEvents(event.Events):
|
||||
globally.
|
||||
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def _accept_with(cls, target):
|
||||
if isinstance(target, orm.scoped_session):
|
||||
@@ -1082,7 +1098,6 @@ class SessionEvents(event.Events):
|
||||
"requires that its creation callable "
|
||||
"is associated with the Session class.")
|
||||
|
||||
|
||||
if isinstance(target, orm.sessionmaker):
|
||||
return target.class_
|
||||
elif isinstance(target, type):
|
||||
@@ -1097,7 +1112,8 @@ class SessionEvents(event.Events):
|
||||
|
||||
@classmethod
|
||||
def _remove(cls, identifier, target, fn):
|
||||
raise NotImplementedError("Removal of session events not yet implemented")
|
||||
msg = "Removal of session events not yet implemented"
|
||||
raise NotImplementedError(msg)
|
||||
|
||||
def after_transaction_create(self, session, transaction):
|
||||
"""Execute when a new :class:`.SessionTransaction` is created.
|
||||
@@ -1176,16 +1192,16 @@ class SessionEvents(event.Events):
|
||||
session.execute("select * from some_table")
|
||||
|
||||
:param session: The target :class:`.Session`.
|
||||
:param previous_transaction: The :class:`.SessionTransaction` transactional
|
||||
marker object which was just closed. The current :class:`.SessionTransaction`
|
||||
for the given :class:`.Session` is available via the
|
||||
:attr:`.Session.transaction` attribute.
|
||||
:param previous_transaction: The :class:`.SessionTransaction`
|
||||
transactional marker object which was just closed. The current
|
||||
:class:`.SessionTransaction` for the given :class:`.Session` is
|
||||
available via the :attr:`.Session.transaction` attribute.
|
||||
|
||||
.. versionadded:: 0.7.3
|
||||
|
||||
"""
|
||||
|
||||
def before_flush( self, session, flush_context, instances):
|
||||
def before_flush(self, session, flush_context, instances):
|
||||
"""Execute before flush process has started.
|
||||
|
||||
:param session: The target :class:`.Session`.
|
||||
@@ -1225,7 +1241,7 @@ class SessionEvents(event.Events):
|
||||
which handles the details of the flush.
|
||||
"""
|
||||
|
||||
def after_begin( self, session, transaction, connection):
|
||||
def after_begin(self, session, transaction, connection):
|
||||
"""Execute after a transaction is begun on a connection
|
||||
|
||||
:param session: The target :class:`.Session`.
|
||||
@@ -1266,7 +1282,7 @@ class SessionEvents(event.Events):
|
||||
|
||||
"""
|
||||
|
||||
def after_bulk_update( self, session, query, query_context, result):
|
||||
def after_bulk_update(self, session, query, query_context, result):
|
||||
"""Execute after a bulk update operation to the session.
|
||||
|
||||
This is called as a result of the :meth:`.Query.update` method.
|
||||
@@ -1280,7 +1296,7 @@ class SessionEvents(event.Events):
|
||||
|
||||
"""
|
||||
|
||||
def after_bulk_delete( self, session, query, query_context, result):
|
||||
def after_bulk_delete(self, session, query, query_context, result):
|
||||
"""Execute after a bulk delete operation to the session.
|
||||
|
||||
This is called as a result of the :meth:`.Query.delete` method.
|
||||
@@ -1372,6 +1388,7 @@ class AttributeEvents(event.Events):
|
||||
|
||||
if not raw or not retval:
|
||||
orig_fn = fn
|
||||
|
||||
def wrap(target, value, *arg):
|
||||
if not raw:
|
||||
target = target.obj()
|
||||
@@ -1392,7 +1409,8 @@ class AttributeEvents(event.Events):
|
||||
|
||||
@classmethod
|
||||
def _remove(cls, identifier, target, fn):
|
||||
raise NotImplementedError("Removal of attribute events not yet implemented")
|
||||
msg = "Removal of attribute events not yet implemented"
|
||||
raise NotImplementedError(msg)
|
||||
|
||||
def append(self, target, value, initiator):
|
||||
"""Receive a collection append event.
|
||||
@@ -1445,4 +1463,3 @@ class AttributeEvents(event.Events):
|
||||
the given value, or a new effective value, should be returned.
|
||||
|
||||
"""
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ attributes = util.importlater('sqlalchemy.orm', 'attributes')
|
||||
NO_STATE = (AttributeError, KeyError)
|
||||
"""Exception types that may be raised by instrumentation implementations."""
|
||||
|
||||
|
||||
class StaleDataError(sa_exc.SQLAlchemyError):
|
||||
"""An operation encountered database state that is unaccounted for.
|
||||
|
||||
@@ -48,13 +49,19 @@ class FlushError(sa_exc.SQLAlchemyError):
|
||||
class UnmappedError(sa_exc.InvalidRequestError):
|
||||
"""Base for exceptions that involve expected mappings not present."""
|
||||
|
||||
|
||||
class ObjectDereferencedError(sa_exc.SQLAlchemyError):
|
||||
"""An operation cannot complete due to an object being garbage collected."""
|
||||
"""An operation cannot complete due to an object being garbage
|
||||
collected.
|
||||
|
||||
"""
|
||||
|
||||
|
||||
class DetachedInstanceError(sa_exc.SQLAlchemyError):
|
||||
"""An attempt to access unloaded attributes on a
|
||||
mapped instance that is detached."""
|
||||
|
||||
|
||||
class UnmappedInstanceError(UnmappedError):
|
||||
"""An mapping operation was requested for an unknown instance."""
|
||||
|
||||
@@ -64,8 +71,9 @@ class UnmappedInstanceError(UnmappedError):
|
||||
mapper = orm_util.class_mapper(type(obj))
|
||||
name = _safe_cls_name(type(obj))
|
||||
msg = ("Class %r is mapped, but this instance lacks "
|
||||
"instrumentation. This occurs when the instance is created "
|
||||
"before sqlalchemy.orm.mapper(%s) was called." % (name, name))
|
||||
"instrumentation. This occurs when the instance"
|
||||
"is created before sqlalchemy.orm.mapper(%s) "
|
||||
"was called." % (name, name))
|
||||
except UnmappedClassError:
|
||||
msg = _default_unmapped(type(obj))
|
||||
if isinstance(obj, type):
|
||||
@@ -77,6 +85,7 @@ class UnmappedInstanceError(UnmappedError):
|
||||
def __reduce__(self):
|
||||
return self.__class__, (None, self.args[0])
|
||||
|
||||
|
||||
class UnmappedClassError(UnmappedError):
|
||||
"""An mapping operation was requested for an unknown class."""
|
||||
|
||||
@@ -88,6 +97,7 @@ class UnmappedClassError(UnmappedError):
|
||||
def __reduce__(self):
|
||||
return self.__class__, (None, self.args[0])
|
||||
|
||||
|
||||
class ObjectDeletedError(sa_exc.InvalidRequestError):
|
||||
"""A refresh operation failed to retrieve the database
|
||||
row corresponding to an object's known primary key identity.
|
||||
@@ -117,6 +127,7 @@ class ObjectDeletedError(sa_exc.InvalidRequestError):
|
||||
def __reduce__(self):
|
||||
return self.__class__, (None, self.args[0])
|
||||
|
||||
|
||||
class UnmappedColumnError(sa_exc.InvalidRequestError):
|
||||
"""Mapping operation was requested on an unknown column."""
|
||||
|
||||
@@ -138,6 +149,7 @@ def _safe_cls_name(cls):
|
||||
cls_name = repr(cls)
|
||||
return cls_name
|
||||
|
||||
|
||||
def _default_unmapped(cls):
|
||||
try:
|
||||
mappers = attributes.manager_of_class(cls).mappers
|
||||
|
||||
Reference in New Issue
Block a user