summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sqlalchemy')
-rw-r--r--lib/sqlalchemy/orm/identity.py20
-rw-r--r--lib/sqlalchemy/orm/instrumentation.py7
-rw-r--r--lib/sqlalchemy/orm/interfaces.py41
-rw-r--r--lib/sqlalchemy/orm/loading.py10
-rw-r--r--lib/sqlalchemy/orm/mapper.py14
-rw-r--r--lib/sqlalchemy/orm/persistence.py26
-rw-r--r--lib/sqlalchemy/orm/properties.py39
-rw-r--r--lib/sqlalchemy/orm/query.py171
-rw-r--r--lib/sqlalchemy/orm/relationships.py85
-rw-r--r--lib/sqlalchemy/orm/scoping.py14
10 files changed, 238 insertions, 189 deletions
diff --git a/lib/sqlalchemy/orm/identity.py b/lib/sqlalchemy/orm/identity.py
index b58aa14a6..e5a2dbb87 100644
--- a/lib/sqlalchemy/orm/identity.py
+++ b/lib/sqlalchemy/orm/identity.py
@@ -39,8 +39,10 @@ class IdentityMap(dict):
return self._modified
def check_modified(self):
- """return True if any InstanceStates present have been marked as 'modified'."""
+ """return True if any InstanceStates present have been marked
+ as 'modified'.
+ """
return bool(self._modified)
def has_key(self, key):
@@ -64,6 +66,7 @@ class IdentityMap(dict):
def __delitem__(self, key):
raise NotImplementedError("IdentityMap uses remove() to remove data")
+
class WeakInstanceDict(IdentityMap):
def __init__(self):
IdentityMap.__init__(self)
@@ -110,9 +113,10 @@ class WeakInstanceDict(IdentityMap):
if existing_state is not state:
o = existing_state.obj()
if o is not None:
- raise AssertionError("A conflicting state is already "
- "present in the identity map for key %r"
- % (key, ))
+ raise AssertionError(
+ "A conflicting state is already "
+ "present in the identity map for key %r"
+ % (key, ))
else:
return
except KeyError:
@@ -156,10 +160,12 @@ class WeakInstanceDict(IdentityMap):
# return iter(self._values())
# Py2K
items = _items
+
def iteritems(self):
return iter(self.items())
values = _values
+
def itervalues(self):
return iter(self.values())
# end Py2K
@@ -180,12 +186,15 @@ class WeakInstanceDict(IdentityMap):
def prune(self):
return 0
+
class StrongInstanceDict(IdentityMap):
def all_states(self):
return [attributes.instance_state(o) for o in self.itervalues()]
def contains_state(self, state):
- return state.key in self and attributes.instance_state(self[state.key]) is state
+ return (
+ state.key in self and
+ attributes.instance_state(self[state.key]) is state)
def replace(self, state):
if dict.__contains__(self, state.key):
@@ -232,4 +241,3 @@ class StrongInstanceDict(IdentityMap):
dict.update(self, keepers)
self.modified = bool(dirty)
return ref_count - len(self)
-
diff --git a/lib/sqlalchemy/orm/instrumentation.py b/lib/sqlalchemy/orm/instrumentation.py
index 0e828ce87..5a4fc2093 100644
--- a/lib/sqlalchemy/orm/instrumentation.py
+++ b/lib/sqlalchemy/orm/instrumentation.py
@@ -32,9 +32,9 @@ alternate instrumentation forms.
from . import exc, collections, events
from operator import attrgetter
from .. import event, util
-import weakref
state = util.importlater("sqlalchemy.orm", "state")
+
class ClassManager(dict):
"""tracks state information at the class level."""
@@ -308,6 +308,7 @@ class ClassManager(dict):
return '<%s of %r at %x>' % (
self.__class__.__name__, self.class_, id(self))
+
class InstrumentationFactory(object):
"""Factory for new ClassManager instances."""
@@ -352,6 +353,7 @@ class InstrumentationFactory(object):
# when importred.
_instrumentation_factory = InstrumentationFactory()
+
def register_class(class_):
"""Register class instrumentation.
@@ -364,6 +366,7 @@ def register_class(class_):
manager = _instrumentation_factory.create_manager_for_cls(class_)
return manager
+
def unregister_class(class_):
"""Unregister class instrumentation."""
@@ -390,6 +393,7 @@ instance_dict = _default_dict_getter = ClassManager.dict_getter()
manager_of_class = _default_manager_getter = ClassManager.manager_getter()
+
def _generate_init(class_, class_manager):
"""Build an __init__ decorator that triggers ClassManager events."""
@@ -433,4 +437,3 @@ def __init__(%(apply_pos)s):
#if func_kw_defaults:
# __init__.__kwdefaults__ = func_kw_defaults
return __init__
-
diff --git a/lib/sqlalchemy/orm/interfaces.py b/lib/sqlalchemy/orm/interfaces.py
index b30630434..c91746da0 100644
--- a/lib/sqlalchemy/orm/interfaces.py
+++ b/lib/sqlalchemy/orm/interfaces.py
@@ -16,7 +16,6 @@ classes within should be considered mostly private.
"""
from __future__ import absolute_import
-from itertools import chain
from .. import exc as sa_exc, util, inspect
from ..sql import operators
@@ -53,6 +52,7 @@ from .deprecated_interfaces import AttributeExtension, \
SessionExtension, \
MapperExtension
+
class _InspectionAttr(object):
"""Define a series of attributes that all ORM inspection
targets need to have."""
@@ -65,11 +65,14 @@ class _InspectionAttr(object):
is_attribute = False
is_clause_element = False
+
class _MappedAttribute(object):
"""Mixin for attributes which should be replaced by mapper-assigned
attributes.
"""
+
+
class MapperProperty(_MappedAttribute, _InspectionAttr):
"""Manage the relationship of a ``Mapper`` to a single class
attribute, as well as that attribute as it appears on individual
@@ -80,7 +83,8 @@ class MapperProperty(_MappedAttribute, _InspectionAttr):
mapped :class:`.Column`, which is represented in a mapping as
an instance of :class:`.ColumnProperty`,
and a reference to another class produced by :func:`.relationship`,
- represented in the mapping as an instance of :class:`.RelationshipProperty`.
+ represented in the mapping as an instance of
+ :class:`.RelationshipProperty`.
"""
@@ -185,7 +189,6 @@ class MapperProperty(_MappedAttribute, _InspectionAttr):
"""
pass
-
def is_primary(self):
"""Return True if this ``MapperProperty``'s mapper is the
primary mapper for its class.
@@ -216,6 +219,7 @@ class MapperProperty(_MappedAttribute, _InspectionAttr):
return operator(self.comparator, value)
+
class PropComparator(operators.ColumnOperators):
"""Defines boolean, comparison, and other operators for
:class:`.MapperProperty` objects.
@@ -223,8 +227,8 @@ class PropComparator(operators.ColumnOperators):
SQLAlchemy allows for operators to
be redefined at both the Core and ORM level. :class:`.PropComparator`
is the base class of operator redefinition for ORM-level operations,
- including those of :class:`.ColumnProperty`, :class:`.RelationshipProperty`,
- and :class:`.CompositeProperty`.
+ including those of :class:`.ColumnProperty`,
+ :class:`.RelationshipProperty`, and :class:`.CompositeProperty`.
.. note:: With the advent of Hybrid properties introduced in SQLAlchemy
0.7, as well as Core-level operator redefinition in
@@ -274,10 +278,10 @@ class PropComparator(operators.ColumnOperators):
class SomeMappedClass(Base):
some_column = column_property(Column("some_column", String),
- comparator_factory=MyColumnComparator)
+ comparator_factory=MyColumnComparator)
some_relationship = relationship(SomeOtherClass,
- comparator_factory=MyRelationshipComparator)
+ comparator_factory=MyRelationshipComparator)
some_composite = composite(
Column("a", String), Column("b", String),
@@ -310,7 +314,6 @@ class PropComparator(operators.ColumnOperators):
self._parentmapper = parentmapper
self.adapter = adapter
-
def __clause_element__(self):
raise NotImplementedError("%r" % self)
@@ -345,8 +348,8 @@ class PropComparator(operators.ColumnOperators):
query.join(Company.employees.of_type(Engineer)).\\
filter(Engineer.name=='foo')
- :param \class_: a class or mapper indicating that criterion will be against
- this specific subclass.
+ :param \class_: a class or mapper indicating that criterion will be
+ against this specific subclass.
"""
@@ -363,9 +366,9 @@ class PropComparator(operators.ColumnOperators):
:param criterion: an optional ClauseElement formulated against the
member class' table or attributes.
- :param \**kwargs: key/value pairs corresponding to member class attribute
- names which will be compared via equality to the corresponding
- values.
+ :param \**kwargs: key/value pairs corresponding to member class
+ attribute names which will be compared via equality to the
+ corresponding values.
"""
@@ -381,9 +384,9 @@ class PropComparator(operators.ColumnOperators):
:param criterion: an optional ClauseElement formulated against the
member class' table or attributes.
- :param \**kwargs: key/value pairs corresponding to member class attribute
- names which will be compared via equality to the corresponding
- values.
+ :param \**kwargs: key/value pairs corresponding to member class
+ attribute names which will be compared via equality to the
+ corresponding values.
"""
@@ -456,6 +459,7 @@ class StrategizedProperty(MapperProperty):
not mapper.class_manager._attr_has_impl(self.key):
self.strategy.init_class_attribute(mapper)
+
class MapperOption(object):
"""Describe a modification to a Query."""
@@ -476,6 +480,7 @@ class MapperOption(object):
self.process_query(query)
+
class PropertyOption(MapperOption):
"""A MapperOption that is applied to a property off the mapper or
one of its child mappers, identified by a dot-separated key
@@ -685,6 +690,7 @@ class PropertyOption(MapperOption):
return paths
+
class StrategizedOption(PropertyOption):
"""A MapperOption that affects which LoaderStrategy will be used
for an operation by a StrategizedProperty.
@@ -711,6 +717,7 @@ class StrategizedOption(PropertyOption):
def get_strategy_class(self):
raise NotImplementedError()
+
class LoaderStrategy(object):
"""Describe the loading behavior of a StrategizedProperty object.
@@ -758,5 +765,3 @@ class LoaderStrategy(object):
def __str__(self):
return str(self.parent_property)
-
-
diff --git a/lib/sqlalchemy/orm/loading.py b/lib/sqlalchemy/orm/loading.py
index df1477210..a5d156a1f 100644
--- a/lib/sqlalchemy/orm/loading.py
+++ b/lib/sqlalchemy/orm/loading.py
@@ -23,6 +23,7 @@ sessionlib = util.importlater("sqlalchemy.orm", "session")
_new_runid = util.counter()
+
def instances(query, cursor, context):
"""Return an ORM result as an iterator."""
session = query.session
@@ -96,6 +97,7 @@ def instances(query, cursor, context):
if not query._yield_per:
break
+
def merge_result(query, iterator, load=True):
"""Merge a result into this :class:`.Query` object's Session."""
@@ -137,6 +139,7 @@ def merge_result(query, iterator, load=True):
finally:
session.autoflush = autoflush
+
def get_from_identity(session, key, passive):
"""Look up the given key in the given session's identity map,
check the object for expired state if found.
@@ -165,6 +168,7 @@ def get_from_identity(session, key, passive):
else:
return None
+
def load_on_ident(query, key,
refresh_state=None, lockmode=None,
only_load_props=None):
@@ -222,6 +226,7 @@ def load_on_ident(query, key,
except orm_exc.NoResultFound:
return None
+
def instance_processor(mapper, context, path, adapter,
polymorphic_from=None,
only_load_props=None,
@@ -475,7 +480,6 @@ def instance_processor(mapper, context, path, adapter,
if isnew:
state.manager.dispatch.refresh(state, context, attrs)
-
if result is not None:
if append_result:
for fn in append_result:
@@ -491,6 +495,7 @@ def instance_processor(mapper, context, path, adapter,
return instance
return _instance
+
def _populators(mapper, context, path, row, adapter,
new_populators, existing_populators, eager_populators):
"""Produce a collection of attribute level row processor
@@ -509,6 +514,7 @@ def _populators(mapper, context, path, row, adapter,
if delayed_populators:
new_populators.extend(delayed_populators)
+
def _configure_subclass_mapper(mapper, context, path, adapter):
"""Produce a mapper level row processor callable factory for mappers
inheriting this one."""
@@ -538,6 +544,7 @@ def _configure_subclass_mapper(mapper, context, path, adapter):
polymorphic_from=mapper)
return configure_subclass_mapper
+
def load_scalar_attributes(mapper, state, attribute_names):
"""initiate a column-based attribute refresh operation."""
@@ -599,4 +606,3 @@ def load_scalar_attributes(mapper, state, attribute_names):
# may not complete (even if PK attributes are assigned)
if has_key and result is None:
raise orm_exc.ObjectDeletedError(state)
-
diff --git a/lib/sqlalchemy/orm/mapper.py b/lib/sqlalchemy/orm/mapper.py
index dfd8a12b7..b89163340 100644
--- a/lib/sqlalchemy/orm/mapper.py
+++ b/lib/sqlalchemy/orm/mapper.py
@@ -54,6 +54,7 @@ NO_ATTRIBUTE = util.symbol('NO_ATTRIBUTE')
# lock used to synchronize the "mapper configure" step
_CONFIGURE_MUTEX = util.threading.RLock()
+
class Mapper(_InspectionAttr):
"""Define the correlation of class attributes to database table
columns.
@@ -629,7 +630,6 @@ class Mapper(_InspectionAttr):
column=None):
self._adapt_inherited_property(key, prop, False)
-
def _set_polymorphic_on(self, polymorphic_on):
self.polymorphic_on = polymorphic_on
self._configure_polymorphic_setter(True)
@@ -745,7 +745,6 @@ class Mapper(_InspectionAttr):
configure_mappers()
return self
-
@property
@util.deprecated("0.7", message=":attr:`.Mapper.compiled` "
"is replaced by :attr:`.Mapper.configured`")
@@ -1051,8 +1050,6 @@ class Mapper(_InspectionAttr):
else:
self._set_polymorphic_identity = None
-
-
def _adapt_inherited_property(self, key, prop, init):
if not self.concrete:
self._configure_property(key, prop, init=False, setparent=False)
@@ -1409,7 +1406,6 @@ class Mapper(_InspectionAttr):
return [self]
return self._mappers_from_spec(*self.with_polymorphic)
-
@_memoized_configured_property
def _with_polymorphic_selectable(self):
if not self.with_polymorphic:
@@ -1822,7 +1818,6 @@ class Mapper(_InspectionAttr):
return state.manager[prop.key].impl.\
get_committed_value(state, dict_, passive=passive)
-
def _optimized_get_statement(self, state, attribute_names):
"""assemble a WHERE clause which retrieves a given state by primary
key, using a minimized set of tables.
@@ -2008,6 +2003,7 @@ class Mapper(_InspectionAttr):
inspection._self_inspects(Mapper)
log.class_logger(Mapper)
+
def configure_mappers():
"""Initialize the inter-mapper relationships of all mappers that
have been constructed thus far.
@@ -2068,6 +2064,7 @@ def configure_mappers():
if _call_configured is not None:
_call_configured.dispatch.after_configured()
+
def reconstructor(fn):
"""Decorate a method as the 'reconstructor' hook.
@@ -2087,6 +2084,7 @@ def reconstructor(fn):
fn.__sa_reconstructor__ = True
return fn
+
def validates(*names, **kw):
"""Decorate a method as a 'validator' for one or more named properties.
@@ -2120,11 +2118,13 @@ def validates(*names, **kw):
return fn
return wrap
+
def _event_on_load(state, ctx):
instrumenting_mapper = state.manager.info[_INSTRUMENTOR]
if instrumenting_mapper._reconstructor:
instrumenting_mapper._reconstructor(state.obj())
+
def _event_on_first_init(manager, cls):
"""Initial mapper compilation trigger.
@@ -2138,6 +2138,7 @@ def _event_on_first_init(manager, cls):
if _new_mappers:
configure_mappers()
+
def _event_on_init(state, args, kwargs):
"""Run init_instance hooks.
@@ -2154,6 +2155,7 @@ def _event_on_init(state, args, kwargs):
if instrumenting_mapper._set_polymorphic_identity:
instrumenting_mapper._set_polymorphic_identity(state)
+
def _event_on_resurrect(state):
# re-populate the primary key elements
# of the dict based on the mapping.
diff --git a/lib/sqlalchemy/orm/persistence.py b/lib/sqlalchemy/orm/persistence.py
index 5945addc4..4774667b2 100644
--- a/lib/sqlalchemy/orm/persistence.py
+++ b/lib/sqlalchemy/orm/persistence.py
@@ -20,6 +20,7 @@ from . import attributes, sync, exc as orm_exc, evaluator
from .util import _state_mapper, state_str, _attr_as_key
from ..sql import expression
+
def save_obj(base_mapper, states, uowtransaction, single=False):
"""Issue ``INSERT`` and/or ``UPDATE`` statements for a list
of objects.
@@ -64,6 +65,7 @@ def save_obj(base_mapper, states, uowtransaction, single=False):
_finalize_insert_update_commands(base_mapper, uowtransaction,
states_to_insert, states_to_update)
+
def post_update(base_mapper, states, uowtransaction, post_update_cols):
"""Issue UPDATE statements on behalf of a relationship() which
specifies post_update.
@@ -75,7 +77,6 @@ def post_update(base_mapper, states, uowtransaction, post_update_cols):
base_mapper,
states, uowtransaction)
-
for table, mapper in base_mapper._sorted_tables.iteritems():
update = _collect_post_update_commands(base_mapper, uowtransaction,
table, states_to_update,
@@ -86,6 +87,7 @@ def post_update(base_mapper, states, uowtransaction, post_update_cols):
cached_connections,
mapper, table, update)
+
def delete_obj(base_mapper, states, uowtransaction):
"""Issue ``DELETE`` statements for a list of objects.
@@ -116,6 +118,7 @@ def delete_obj(base_mapper, states, uowtransaction):
in states_to_delete:
mapper.dispatch.after_delete(mapper, connection, state)
+
def _organize_states_for_save(base_mapper, states, uowtransaction):
"""Make an initial pass across a set of states for INSERT or
UPDATE.
@@ -185,6 +188,7 @@ def _organize_states_for_save(base_mapper, states, uowtransaction):
return states_to_insert, states_to_update
+
def _organize_states_for_post_update(base_mapper, states,
uowtransaction):
"""Make an initial pass across a set of states for UPDATE
@@ -198,6 +202,7 @@ def _organize_states_for_post_update(base_mapper, states,
return list(_connections_for_states(base_mapper, uowtransaction,
states))
+
def _organize_states_for_delete(base_mapper, states, uowtransaction):
"""Make an initial pass across a set of states for DELETE.
@@ -218,6 +223,7 @@ def _organize_states_for_delete(base_mapper, states, uowtransaction):
bool(state.key), connection))
return states_to_delete
+
def _collect_insert_commands(base_mapper, uowtransaction, table,
states_to_insert):
"""Identify sets of values to use in INSERT statements for a
@@ -261,6 +267,7 @@ def _collect_insert_commands(base_mapper, uowtransaction, table,
connection, value_params, has_all_pks))
return insert
+
def _collect_update_commands(base_mapper, uowtransaction,
table, states_to_update):
"""Identify sets of values to use in UPDATE statements for a
@@ -412,6 +419,7 @@ def _collect_post_update_commands(base_mapper, uowtransaction, table,
connection))
return update
+
def _collect_delete_commands(base_mapper, uowtransaction, table,
states_to_delete):
"""Identify values to use in DELETE statements for a list of
@@ -507,6 +515,7 @@ def _emit_update_statements(base_mapper, uowtransaction,
c.dialect.dialect_description,
stacklevel=12)
+
def _emit_insert_statements(base_mapper, uowtransaction,
cached_connections, table, insert):
"""Emit INSERT statements corresponding to value lists collected
@@ -582,7 +591,6 @@ def _emit_insert_statements(base_mapper, uowtransaction,
value_params)
-
def _emit_post_update_statements(base_mapper, uowtransaction,
cached_connections, mapper, table, update):
"""Emit UPDATE statements corresponding to value lists collected
@@ -703,6 +711,7 @@ def _finalize_insert_update_commands(base_mapper, uowtransaction,
else:
mapper.dispatch.after_update(mapper, connection, state)
+
def _postfetch(mapper, uowtransaction, table,
state, dict_, prefetch_cols, postfetch_cols,
params, value_params):
@@ -733,6 +742,7 @@ def _postfetch(mapper, uowtransaction, table,
uowtransaction,
mapper.passive_updates)
+
def _connections_for_states(base_mapper, uowtransaction, states):
"""Return an iterator of (state, state.dict, mapper, connection).
@@ -762,6 +772,7 @@ def _connections_for_states(base_mapper, uowtransaction, states):
yield state, state.dict, mapper, connection
+
def _cached_connection_dict(base_mapper):
# dictionary of connection->connection_with_cache_options.
return util.PopulateDict(
@@ -769,6 +780,7 @@ def _cached_connection_dict(base_mapper):
compiled_cache=base_mapper._compiled_cache
))
+
def _sort_states(states):
pending = set(states)
persistent = set(s for s in pending if s.key is not None)
@@ -776,6 +788,7 @@ def _sort_states(states):
return sorted(pending, key=operator.attrgetter("insert_order")) + \
sorted(persistent, key=lambda q: q.key[1])
+
class BulkUD(object):
"""Handle bulk update and deletes via a :class:`.Query`."""
@@ -825,6 +838,7 @@ class BulkUD(object):
def _do_post_synchronize(self):
pass
+
class BulkEvaluate(BulkUD):
"""BulkUD which does the 'evaluate' method of session state resolution."""
@@ -858,6 +872,7 @@ class BulkEvaluate(BulkUD):
if issubclass(cls, target_cls) and
eval_condition(obj)]
+
class BulkFetch(BulkUD):
"""BulkUD which does the 'fetch' method of session state resolution."""
@@ -870,6 +885,7 @@ class BulkFetch(BulkUD):
select_stmt,
params=query._params).fetchall()
+
class BulkUpdate(BulkUD):
"""BulkUD which handles UPDATEs."""
@@ -899,6 +915,7 @@ class BulkUpdate(BulkUD):
session.dispatch.after_bulk_update(session, self.query,
self.context, self.result)
+
class BulkDelete(BulkUD):
"""BulkUD which handles DELETEs."""
@@ -927,6 +944,7 @@ class BulkDelete(BulkUD):
session.dispatch.after_bulk_delete(session, self.query,
self.context, self.result)
+
class BulkUpdateEvaluate(BulkEvaluate, BulkUpdate):
"""BulkUD which handles UPDATEs using the "evaluate"
method of session resolution."""
@@ -962,6 +980,7 @@ class BulkUpdateEvaluate(BulkEvaluate, BulkUpdate):
states.add(state)
session._register_altered(states)
+
class BulkDeleteEvaluate(BulkEvaluate, BulkDelete):
"""BulkUD which handles DELETEs using the "evaluate"
method of session resolution."""
@@ -971,6 +990,7 @@ class BulkDeleteEvaluate(BulkEvaluate, BulkDelete):
[attributes.instance_state(obj)
for obj in self.matched_objects])
+
class BulkUpdateFetch(BulkFetch, BulkUpdate):
"""BulkUD which handles UPDATEs using the "fetch"
method of session resolution."""
@@ -993,6 +1013,7 @@ class BulkUpdateFetch(BulkFetch, BulkUpdate):
session._expire_state(state, attrib)
session._register_altered(states)
+
class BulkDeleteFetch(BulkFetch, BulkDelete):
"""BulkUD which handles DELETEs using the "fetch"
method of session resolution."""
@@ -1011,4 +1032,3 @@ class BulkDeleteFetch(BulkFetch, BulkDelete):
session.identity_map[identity_key]
)]
)
-
diff --git a/lib/sqlalchemy/orm/properties.py b/lib/sqlalchemy/orm/properties.py
index e2b5e94e0..12656952a 100644
--- a/lib/sqlalchemy/orm/properties.py
+++ b/lib/sqlalchemy/orm/properties.py
@@ -44,7 +44,8 @@ class ColumnProperty(StrategizedProperty):
def __init__(self, *columns, **kwargs):
"""Construct a ColumnProperty.
- Note the public constructor is the :func:`.orm.column_property` function.
+ Note the public constructor is the :func:`.orm.column_property`
+ function.
:param \*columns: The list of `columns` describes a single
object property. If there are multiple tables joined
@@ -108,7 +109,6 @@ class ColumnProperty(StrategizedProperty):
else:
self.strategy_class = strategies.ColumnLoader
-
@property
def expression(self):
"""Return the primary column or expression for this ColumnProperty.
@@ -170,7 +170,8 @@ class ColumnProperty(StrategizedProperty):
"""Produce boolean, comparison, and other operators for
:class:`.ColumnProperty` attributes.
- See the documentation for :class:`.PropComparator` for a brief overview.
+ See the documentation for :class:`.PropComparator` for a brief
+ overview.
See also:
@@ -189,8 +190,8 @@ class ColumnProperty(StrategizedProperty):
return self.adapter(self.prop.columns[0])
else:
return self.prop.columns[0]._annotate({
- "parententity": self._parentmapper,
- "parentmapper": self._parentmapper})
+ "parententity": self._parentmapper,
+ "parentmapper": self._parentmapper})
def __getattr__(self, key):
"""proxy attribute access down to the mapped column.
@@ -214,6 +215,7 @@ class ColumnProperty(StrategizedProperty):
log.class_logger(ColumnProperty)
+
class RelationshipProperty(StrategizedProperty):
"""Describes an object property that holds a single item or list
of items that correspond to a related database table.
@@ -541,7 +543,8 @@ class RelationshipProperty(StrategizedProperty):
# should not correlate or otherwise reach out
# to anything in the enclosing query.
if criterion is not None:
- criterion = criterion._annotate({'no_replacement_traverse': True})
+ criterion = criterion._annotate(
+ {'no_replacement_traverse': True})
crit = j & criterion
@@ -582,7 +585,8 @@ class RelationshipProperty(StrategizedProperty):
will produce::
SELECT * FROM my_table WHERE
- NOT EXISTS (SELECT 1 FROM related WHERE related.my_id=my_table.id)
+ NOT EXISTS (SELECT 1 FROM related WHERE
+ related.my_id=my_table.id)
:meth:`~.RelationshipProperty.Comparator.any` is only
valid for collections, i.e. a :func:`.relationship`
@@ -612,8 +616,8 @@ class RelationshipProperty(StrategizedProperty):
Will produce a query like::
SELECT * FROM my_table WHERE
- EXISTS (SELECT 1 FROM related WHERE related.id==my_table.related_id
- AND related.x=2)
+ EXISTS (SELECT 1 FROM related WHERE
+ related.id==my_table.related_id AND related.x=2)
Because :meth:`~.RelationshipProperty.Comparator.has` uses
a correlated subquery, its performance is not nearly as
@@ -706,10 +710,9 @@ class RelationshipProperty(StrategizedProperty):
state = attributes.instance_state(other)
def state_bindparam(x, state, col):
- o = state.obj() # strong ref
- return sql.bindparam(x, unique=True, callable_=lambda : \
- self.property.mapper._get_committed_attr_by_column(o,
- col))
+ o = state.obj() # strong ref
+ return sql.bindparam(x, unique=True, callable_=lambda: \
+ self.property.mapper._get_committed_attr_by_column(o, col))
def adapt(col):
if self.adapter:
@@ -724,7 +727,7 @@ class RelationshipProperty(StrategizedProperty):
adapt(x) == None)
for (x, y) in self.property.local_remote_pairs])
- criterion = sql.and_(*[x==y for (x, y) in
+ criterion = sql.and_(*[x == y for (x, y) in
zip(
self.property.mapper.primary_key,
self.property.\
@@ -835,7 +838,6 @@ class RelationshipProperty(StrategizedProperty):
if (source_state, r) in _recursive:
return
-
if not "merge" in self.cascade:
return
@@ -912,8 +914,8 @@ class RelationshipProperty(StrategizedProperty):
else:
return [(attributes.instance_state(x), x)]
-
- def cascade_iterator(self, type_, state, dict_, visited_states, halt_on=None):
+ def cascade_iterator(self, type_, state, dict_,
+ visited_states, halt_on=None):
#assert type_ in self.cascade
# only actively lazy load on the 'delete' cascade
@@ -967,7 +969,6 @@ class RelationshipProperty(StrategizedProperty):
yield c, instance_mapper, instance_state, instance_dict
-
def _add_reverse_property(self, key):
other = self.mapper.get_property(key, _configure_mappers=False)
self._reverse_property.add(other)
@@ -1140,7 +1141,6 @@ class RelationshipProperty(StrategizedProperty):
"cause dependency issues during flush"
% (self.key, self.parent, inheriting))
-
def _check_cascade_settings(self):
if self.cascade.delete_orphan and not self.single_parent \
and (self.direction is MANYTOMANY or self.direction
@@ -1288,4 +1288,3 @@ class RelationshipProperty(StrategizedProperty):
PropertyLoader = RelationProperty = RelationshipProperty
log.class_logger(RelationshipProperty)
-
diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py
index a34fd882a..ca334e273 100644
--- a/lib/sqlalchemy/orm/query.py
+++ b/lib/sqlalchemy/orm/query.py
@@ -27,7 +27,7 @@ from . import (
from .util import (
AliasedClass, ORMAdapter, _entity_descriptor, PathRegistry,
_is_aliased_class, _is_mapped_class, _orm_columns,
- join as orm_join,with_parent, aliased
+ join as orm_join, with_parent, aliased
)
from .. import sql, util, log, exc as sa_exc, inspect, inspection, \
types as sqltypes
@@ -54,6 +54,7 @@ def _generative(*assertions):
_path_registry = PathRegistry.root
+
class Query(object):
"""ORM-level SQL construction object.
@@ -177,7 +178,6 @@ class Query(object):
self._from_obj_alias = sql_util.ColumnAdapter(
self._from_obj[0], equivs)
-
def _reset_polymorphic_adapter(self, mapper):
for m2 in mapper._with_polymorphic_mappers:
self._polymorphic_adapters.pop(m2, None)
@@ -274,7 +274,6 @@ class Query(object):
return self._select_from_entity or \
self._entity_zero().entity_zero
-
@property
def _mapper_entities(self):
# TODO: this is wrong, its hardcoded to "primary entity" when
@@ -325,7 +324,6 @@ class Query(object):
)
return self._entity_zero()
-
def __all_equivs(self):
equivs = {}
for ent in self._mapper_entities:
@@ -540,10 +538,9 @@ class Query(object):
return self.enable_eagerloads(False).statement.label(name)
-
def as_scalar(self):
- """Return the full SELECT statement represented by this :class:`.Query`, converted
- to a scalar subquery.
+ """Return the full SELECT statement represented by this
+ :class:`.Query`, converted to a scalar subquery.
Analogous to :meth:`sqlalchemy.sql.SelectBaseMixin.as_scalar`.
@@ -618,7 +615,8 @@ class Query(object):
@property
def whereclause(self):
- """A readonly attribute which returns the current WHERE criterion for this Query.
+ """A readonly attribute which returns the current WHERE criterion for
+ this Query.
This returned value is a SQL expression construct, or ``None`` if no
criterion has been established.
@@ -648,11 +646,11 @@ class Query(object):
:meth:`.Query.with_polymorphic` applies transformations
to the "main" mapped class represented by this :class:`.Query`.
The "main" mapped class here means the :class:`.Query`
- object's first argument is a full class, i.e. ``session.query(SomeClass)``.
- These transformations allow additional tables to be present
- in the FROM clause so that columns for a joined-inheritance
- subclass are available in the query, both for the purposes
- of load-time efficiency as well as the ability to use
+ object's first argument is a full class, i.e.
+ ``session.query(SomeClass)``. These transformations allow additional
+ tables to be present in the FROM clause so that columns for a
+ joined-inheritance subclass are available in the query, both for the
+ purposes of load-time efficiency as well as the ability to use
these columns at query time.
See the documentation section :ref:`with_polymorphic` for
@@ -783,7 +781,8 @@ class Query(object):
not mapper.always_refresh and \
self._lockmode is None:
- instance = loading.get_from_identity(self.session, key, attributes.PASSIVE_OFF)
+ instance = loading.get_from_identity(
+ self.session, key, attributes.PASSIVE_OFF)
if instance is not None:
# reject calls for id in identity map but class
# mismatch.
@@ -980,8 +979,8 @@ class Query(object):
@_generative()
def with_entities(self, *entities):
- """Return a new :class:`.Query` replacing the SELECT list with the given
- entities.
+ """Return a new :class:`.Query` replacing the SELECT list with the
+ given entities.
e.g.::
@@ -1006,7 +1005,6 @@ class Query(object):
"""
self._set_entities(entities)
-
@_generative()
def add_columns(self, *column):
"""Add one or more column expressions to the list
@@ -1024,13 +1022,13 @@ class Query(object):
":meth:`.add_column` is superseded by :meth:`.add_columns`",
False)
def add_column(self, column):
- """Add a column expression to the list of result columns to be returned.
+ """Add a column expression to the list of result columns to be
+ returned.
Pending deprecation: :meth:`.add_column` will be superseded by
:meth:`.add_columns`.
"""
-
return self.add_columns(column)
def options(self, *args):
@@ -1340,9 +1338,8 @@ class Query(object):
"""
-
return self._from_selectable(
- expression.union(*([self]+ list(q))))
+ expression.union(*([self] + list(q))))
def union_all(self, *q):
"""Produce a UNION ALL of this Query against one or more queries.
@@ -1352,7 +1349,7 @@ class Query(object):
"""
return self._from_selectable(
- expression.union_all(*([self]+ list(q)))
+ expression.union_all(*([self] + list(q)))
)
def intersect(self, *q):
@@ -1363,7 +1360,7 @@ class Query(object):
"""
return self._from_selectable(
- expression.intersect(*([self]+ list(q)))
+ expression.intersect(*([self] + list(q)))
)
def intersect_all(self, *q):
@@ -1374,7 +1371,7 @@ class Query(object):
"""
return self._from_selectable(
- expression.intersect_all(*([self]+ list(q)))
+ expression.intersect_all(*([self] + list(q)))
)
def except_(self, *q):
@@ -1385,7 +1382,7 @@ class Query(object):
"""
return self._from_selectable(
- expression.except_(*([self]+ list(q)))
+ expression.except_(*([self] + list(q)))
)
def except_all(self, *q):
@@ -1396,7 +1393,7 @@ class Query(object):
"""
return self._from_selectable(
- expression.except_all(*([self]+ list(q)))
+ expression.except_all(*([self] + list(q)))
)
def join(self, *props, **kwargs):
@@ -1422,9 +1419,9 @@ class Query(object):
In the above example we refer to ``User.addresses`` as passed to
:meth:`~.Query.join` as the *on clause*, that is, it indicates
how the "ON" portion of the JOIN should be constructed. For a
- single-entity query such as the one above (i.e. we start by selecting only from
- ``User`` and nothing else), the relationship can also be specified by its
- string name::
+ single-entity query such as the one above (i.e. we start by selecting
+ only from ``User`` and nothing else), the relationship can also be
+ specified by its string name::
q = session.query(User).join("addresses")
@@ -1434,8 +1431,9 @@ class Query(object):
q = session.query(User).join("orders", "items", "keywords")
- The above would be shorthand for three separate calls to :meth:`~.Query.join`,
- each using an explicit attribute to indicate the source entity::
+ The above would be shorthand for three separate calls to
+ :meth:`~.Query.join`, each using an explicit attribute to indicate
+ the source entity::
q = session.query(User).\\
join(User.orders).\\
@@ -1511,25 +1509,26 @@ class Query(object):
There is a lot of flexibility in what the "target" can be when using
:meth:`~.Query.join`. As noted previously, it also accepts
- :class:`.Table` constructs and other selectables such as :func:`.alias`
- and :func:`.select` constructs, with either the one or two-argument forms::
+ :class:`.Table` constructs and other selectables such as
+ :func:`.alias` and :func:`.select` constructs, with either the one
+ or two-argument forms::
addresses_q = select([Address.user_id]).\\
- where(Address.email_address.endswith("@bar.com")).\\
- alias()
+ where(Address.email_address.endswith("@bar.com")).\\
+ alias()
q = session.query(User).\\
join(addresses_q, addresses_q.c.user_id==User.id)
:meth:`~.Query.join` also features the ability to *adapt* a
- :meth:`~sqlalchemy.orm.relationship` -driven ON clause to the target selectable.
- Below we construct a JOIN from ``User`` to a subquery against ``Address``, allowing
- the relationship denoted by ``User.addresses`` to *adapt* itself
- to the altered target::
+ :meth:`~sqlalchemy.orm.relationship` -driven ON clause to the target
+ selectable. Below we construct a JOIN from ``User`` to a subquery
+ against ``Address``, allowing the relationship denoted by
+ ``User.addresses`` to *adapt* itself to the altered target::
address_subq = session.query(Address).\\
- filter(Address.email_address == 'ed@foo.com').\\
- subquery()
+ filter(Address.email_address == 'ed@foo.com').\\
+ subquery()
q = session.query(User).join(address_subq, User.addresses)
@@ -1811,7 +1810,7 @@ class Query(object):
if not create_aliases and prop:
self._update_joinpoint({
'_joinpoint_entity': right,
- 'prev':((left, right, prop.key), self._joinpoint)
+ 'prev': ((left, right, prop.key), self._joinpoint)
})
else:
self._joinpoint = {
@@ -2051,7 +2050,7 @@ class Query(object):
if item == -1:
return list(self)[-1]
else:
- return list(self[item:item+1])[0]
+ return list(self[item:item + 1])[0]
@_generative(_no_statement_condition)
def slice(self, start, stop):
@@ -2261,8 +2260,8 @@ class Query(object):
def _execute_and_instances(self, querycontext):
conn = self._connection_from_session(
- mapper = self._mapper_zero_or_none(),
- clause = querycontext.statement,
+ mapper=self._mapper_zero_or_none(),
+ clause=querycontext.statement,
close_with_result=True)
result = conn.execute(querycontext.statement, self._params)
@@ -2330,20 +2329,20 @@ class Query(object):
return loading.instances(self, cursor, context)
-
def merge_result(self, iterator, load=True):
"""Merge a result into this :class:`.Query` object's Session.
- Given an iterator returned by a :class:`.Query` of the same structure as this
- one, return an identical iterator of results, with all mapped
- instances merged into the session using :meth:`.Session.merge`. This is an
- optimized method which will merge all mapped instances, preserving the
- structure of the result rows and unmapped columns with less method
- overhead than that of calling :meth:`.Session.merge` explicitly for each
- value.
+ Given an iterator returned by a :class:`.Query` of the same structure
+ as this one, return an identical iterator of results, with all mapped
+ instances merged into the session using :meth:`.Session.merge`. This
+ is an optimized method which will merge all mapped instances,
+ preserving the structure of the result rows and unmapped columns with
+ less method overhead than that of calling :meth:`.Session.merge`
+ explicitly for each value.
The structure of the results is determined based on the column list of
- this :class:`.Query` - if these do not correspond, unchecked errors will occur.
+ this :class:`.Query` - if these do not correspond, unchecked errors
+ will occur.
The 'load' argument is the same as that of :meth:`.Session.merge`.
@@ -2359,12 +2358,12 @@ class Query(object):
@property
def _select_args(self):
return {
- 'limit':self._limit,
- 'offset':self._offset,
- 'distinct':self._distinct,
- 'prefixes':self._prefixes,
- 'group_by':self._group_by or None,
- 'having':self._having
+ 'limit': self._limit,
+ 'offset': self._offset,
+ 'distinct': self._distinct,
+ 'prefixes': self._prefixes,
+ 'group_by': self._group_by or None,
+ 'having': self._having
}
@property
@@ -2435,8 +2434,8 @@ class Query(object):
removed from the session. Matched objects are removed from the
session.
- ``'evaluate'`` - Evaluate the query's criteria in Python straight on
- the objects in the session. If evaluation of the criteria isn't
+ ``'evaluate'`` - Evaluate the query's criteria in Python straight
+ on the objects in the session. If evaluation of the criteria isn't
implemented, an error is raised. In that case you probably
want to use the 'fetch' strategy as a fallback.
@@ -2487,8 +2486,8 @@ class Query(object):
objects that are matched by the update query. The updated
attributes are expired on matched objects.
- ``'evaluate'`` - Evaluate the Query's criteria in Python straight on
- the objects in the session. If evaluation of the criteria isn't
+ ``'evaluate'`` - Evaluate the Query's criteria in Python straight
+ on the objects in the session. If evaluation of the criteria isn't
implemented, an exception is raised.
The expression evaluator currently doesn't account for differing
@@ -2522,7 +2521,6 @@ class Query(object):
update_op.exec_()
return update_op.rowcount
-
_lockmode_lookup = {
'read': 'read',
'read_nowait': 'read_nowait',
@@ -2708,6 +2706,7 @@ class Query(object):
inspection._self_inspects(Query)
+
class _QueryEntity(object):
"""represent an entity column returned within a Query result."""
@@ -2726,6 +2725,7 @@ class _QueryEntity(object):
q.__dict__ = self.__dict__.copy()
return q
+
class _MapperEntity(_QueryEntity):
"""mapper/class/AliasedClass entity"""
@@ -2739,7 +2739,7 @@ class _MapperEntity(_QueryEntity):
def setup_entity(self, ext_info, aliased_adapter):
self.mapper = ext_info.mapper
self.aliased_adapter = aliased_adapter
- self.selectable = ext_info.selectable
+ self.selectable = ext_info.selectable
self.is_aliased_class = ext_info.is_aliased_class
self._with_polymorphic = ext_info.with_polymorphic_mappers
self._polymorphic_discriminator = \
@@ -2829,28 +2829,27 @@ class _MapperEntity(_QueryEntity):
# require row aliasing unconditionally.
if not adapter and self.mapper._requires_row_aliasing:
adapter = sql_util.ColumnAdapter(
- self.selectable,
- self.mapper._equivalent_columns)
+ self.selectable,
+ self.mapper._equivalent_columns)
if self.primary_entity:
_instance = loading.instance_processor(
- self.mapper,
- context,
- self.path,
- adapter,
- only_load_props=query._only_load_props,
- refresh_state=context.refresh_state,
- polymorphic_discriminator=
- self._polymorphic_discriminator
+ self.mapper,
+ context,
+ self.path,
+ adapter,
+ only_load_props=query._only_load_props,
+ refresh_state=context.refresh_state,
+ polymorphic_discriminator=self._polymorphic_discriminator
)
else:
_instance = loading.instance_processor(
- self.mapper,
- context,
- self.path,
- adapter,
- polymorphic_discriminator=
- self._polymorphic_discriminator)
+ self.mapper,
+ context,
+ self.path,
+ adapter,
+ polymorphic_discriminator=self._polymorphic_discriminator
+ )
return _instance, self._label_name
@@ -2902,6 +2901,7 @@ class _MapperEntity(_QueryEntity):
def __str__(self):
return str(self.mapper)
+
class _ColumnEntity(_QueryEntity):
"""Column/expression based entity."""
@@ -2931,7 +2931,6 @@ class _ColumnEntity(_QueryEntity):
if c is not column:
return
-
if not isinstance(column, sql.ColumnElement):
raise sa_exc.InvalidRequestError(
"SQL expression, column, or mapped entity "
@@ -2981,7 +2980,6 @@ class _ColumnEntity(_QueryEntity):
else:
self.entity_zero = None
-
@property
def entity_zero_or_selectable(self):
if self.entity_zero is not None:
@@ -2995,7 +2993,6 @@ class _ColumnEntity(_QueryEntity):
def type(self):
return self.column.type
-
def adapt_to_selectable(self, query, sel):
c = _ColumnEntity(query, sel.corresponding_column(self.column))
c._label_name = self._label_name
@@ -3040,8 +3037,10 @@ class _ColumnEntity(_QueryEntity):
def __str__(self):
return str(self.column)
+
log.class_logger(Query)
+
class QueryContext(object):
multi_row_eager_loaders = False
adapter = None
@@ -3089,5 +3088,3 @@ class AliasOption(interfaces.MapperOption):
else:
alias = self.alias
query._from_obj_alias = sql_util.ColumnAdapter(alias)
-
-
diff --git a/lib/sqlalchemy/orm/relationships.py b/lib/sqlalchemy/orm/relationships.py
index 373fba785..24ca32d9a 100644
--- a/lib/sqlalchemy/orm/relationships.py
+++ b/lib/sqlalchemy/orm/relationships.py
@@ -22,6 +22,7 @@ from ..sql.util import (
from ..sql import operators, expression, visitors
from .interfaces import MANYTOMANY, MANYTOONE, ONETOMANY
+
def remote(expr):
"""Annotate a portion of a primaryjoin expression
with a 'remote' annotation.
@@ -41,6 +42,7 @@ def remote(expr):
return _annotate_columns(expression._clause_element_as_expr(expr),
{"remote": True})
+
def foreign(expr):
"""Annotate a portion of a primaryjoin expression
with a 'foreign' annotation.
@@ -73,6 +75,7 @@ def _annotate_columns(element, annotations):
element = clone(element)
return element
+
class JoinCondition(object):
def __init__(self,
parent_selectable,
@@ -166,35 +169,33 @@ class JoinCondition(object):
# general mapped table, which in the case of inheritance is
# a join.
try:
+ consider_as_foreign_keys = self.consider_as_foreign_keys or None
if self.secondary is not None:
if self.secondaryjoin is None:
self.secondaryjoin = \
join_condition(
- self.child_selectable,
- self.secondary,
- a_subset=self.child_local_selectable,
- consider_as_foreign_keys=\
- self.consider_as_foreign_keys or None
- )
+ self.child_selectable,
+ self.secondary,
+ a_subset=self.child_local_selectable,
+ consider_as_foreign_keys=consider_as_foreign_keys
+ )
if self.primaryjoin is None:
self.primaryjoin = \
join_condition(
- self.parent_selectable,
- self.secondary,
- a_subset=self.parent_local_selectable,
- consider_as_foreign_keys=\
- self.consider_as_foreign_keys or None
- )
+ self.parent_selectable,
+ self.secondary,
+ a_subset=self.parent_local_selectable,
+ consider_as_foreign_keys=consider_as_foreign_keys
+ )
else:
if self.primaryjoin is None:
self.primaryjoin = \
join_condition(
- self.parent_selectable,
- self.child_selectable,
- a_subset=self.parent_local_selectable,
- consider_as_foreign_keys=\
- self.consider_as_foreign_keys or None
- )
+ self.parent_selectable,
+ self.child_selectable,
+ a_subset=self.parent_local_selectable,
+ consider_as_foreign_keys=consider_as_foreign_keys
+ )
except sa_exc.NoForeignKeysError:
if self.secondary is not None:
raise sa_exc.NoForeignKeysError("Could not determine join "
@@ -312,7 +313,7 @@ class JoinCondition(object):
def _annotate_from_fk_list(self):
def check_fk(col):
if col in self.consider_as_foreign_keys:
- return col._annotate({"foreign":True})
+ return col._annotate({"foreign": True})
self.primaryjoin = visitors.replacement_traverse(
self.primaryjoin,
{},
@@ -330,6 +331,7 @@ class JoinCondition(object):
secondarycols = util.column_set(self.secondary.c)
else:
secondarycols = set()
+
def is_foreign(a, b):
if isinstance(a, schema.Column) and \
isinstance(b, schema.Column):
@@ -355,21 +357,21 @@ class JoinCondition(object):
if col is not None:
if col.compare(binary.left):
binary.left = binary.left._annotate(
- {"foreign":True})
+ {"foreign": True})
elif col.compare(binary.right):
binary.right = binary.right._annotate(
- {"foreign":True})
+ {"foreign": True})
self.primaryjoin = visitors.cloned_traverse(
self.primaryjoin,
{},
- {"binary":visit_binary}
+ {"binary": visit_binary}
)
if self.secondaryjoin is not None:
self.secondaryjoin = visitors.cloned_traverse(
self.secondaryjoin,
{},
- {"binary":visit_binary}
+ {"binary": visit_binary}
)
def _refers_to_parent_table(self):
@@ -380,6 +382,7 @@ class JoinCondition(object):
pt = self.parent_selectable
mt = self.child_selectable
result = [False]
+
def visit_binary(binary):
c, f = binary.left, binary.right
if (
@@ -394,7 +397,7 @@ class JoinCondition(object):
visitors.traverse(
self.primaryjoin,
{},
- {"binary":visit_binary}
+ {"binary": visit_binary}
)
return result[0]
@@ -421,7 +424,7 @@ class JoinCondition(object):
elif self._local_remote_pairs or self._remote_side:
self._annotate_remote_from_args()
elif self._refers_to_parent_table():
- self._annotate_selfref(lambda col:"foreign" in col._annotations)
+ self._annotate_selfref(lambda col: "foreign" in col._annotations)
elif self._tables_overlap():
self._annotate_remote_with_overlap()
else:
@@ -434,7 +437,7 @@ class JoinCondition(object):
"""
def repl(element):
if self.secondary.c.contains_column(element):
- return element._annotate({"remote":True})
+ return element._annotate({"remote": True})
self.primaryjoin = visitors.replacement_traverse(
self.primaryjoin, {}, repl)
self.secondaryjoin = visitors.replacement_traverse(
@@ -451,17 +454,17 @@ class JoinCondition(object):
isinstance(binary.right, expression.ColumnClause):
# assume one to many - FKs are "remote"
if fn(binary.left):
- binary.left = binary.left._annotate({"remote":True})
+ binary.left = binary.left._annotate({"remote": True})
if fn(binary.right) and \
not equated:
binary.right = binary.right._annotate(
- {"remote":True})
+ {"remote": True})
else:
self._warn_non_column_elements()
self.primaryjoin = visitors.cloned_traverse(
self.primaryjoin, {},
- {"binary":visit_binary})
+ {"binary": visit_binary})
def _annotate_remote_from_args(self):
"""annotate 'remote' in primaryjoin, secondaryjoin
@@ -481,11 +484,11 @@ class JoinCondition(object):
remote_side = self._remote_side
if self._refers_to_parent_table():
- self._annotate_selfref(lambda col:col in remote_side)
+ self._annotate_selfref(lambda col: col in remote_side)
else:
def repl(element):
if element in remote_side:
- return element._annotate({"remote":True})
+ return element._annotate({"remote": True})
self.primaryjoin = visitors.replacement_traverse(
self.primaryjoin, {}, repl)
@@ -501,20 +504,21 @@ class JoinCondition(object):
binary.right)
binary.right, binary.left = proc_left_right(binary.right,
binary.left)
+
def proc_left_right(left, right):
if isinstance(left, expression.ColumnClause) and \
isinstance(right, expression.ColumnClause):
if self.child_selectable.c.contains_column(right) and \
self.parent_selectable.c.contains_column(left):
- right = right._annotate({"remote":True})
+ right = right._annotate({"remote": True})
else:
- self._warn_non_column_elements()
+ self._warn_non_column_elements()
return left, right
self.primaryjoin = visitors.cloned_traverse(
self.primaryjoin, {},
- {"binary":visit_binary})
+ {"binary": visit_binary})
def _annotate_remote_distinct_selectables(self):
"""annotate 'remote' in primaryjoin, secondaryjoin
@@ -530,7 +534,7 @@ class JoinCondition(object):
or self.child_local_selectable.c.\
contains_column(element)
):
- return element._annotate({"remote":True})
+ return element._annotate({"remote": True})
self.primaryjoin = visitors.replacement_traverse(
self.primaryjoin, {}, repl)
@@ -565,7 +569,7 @@ class JoinCondition(object):
def locals_(elem):
if "remote" not in elem._annotations and \
elem in local_side:
- return elem._annotate({"local":True})
+ return elem._annotate({"local": True})
self.primaryjoin = visitors.replacement_traverse(
self.primaryjoin, {}, locals_
)
@@ -736,7 +740,8 @@ class JoinCondition(object):
self.local_remote_pairs = self._deannotate_pairs(lrp)
self.synchronize_pairs = self._deannotate_pairs(sync_pairs)
- self.secondary_synchronize_pairs = self._deannotate_pairs(secondary_sync_pairs)
+ self.secondary_synchronize_pairs = \
+ self._deannotate_pairs(secondary_sync_pairs)
@util.memoized_property
def remote_columns(self):
@@ -780,7 +785,6 @@ class JoinCondition(object):
if annotation.issubset(col._annotations)
])
-
def join_targets(self, source_selectable,
dest_selectable,
aliased,
@@ -801,7 +805,7 @@ class JoinCondition(object):
# regardless of context.
dest_selectable = _shallow_annotate(
dest_selectable,
- {'no_replacement_traverse':True})
+ {'no_replacement_traverse': True})
primaryjoin, secondaryjoin, secondary = self.primaryjoin, \
self.secondaryjoin, self.secondary
@@ -894,6 +898,3 @@ class JoinCondition(object):
bind_to_col = dict((binds[col].key, col) for col in binds)
return lazywhere, bind_to_col, equated_columns
-
-
-
diff --git a/lib/sqlalchemy/orm/scoping.py b/lib/sqlalchemy/orm/scoping.py
index 3c4a0e5d8..e0ee62012 100644
--- a/lib/sqlalchemy/orm/scoping.py
+++ b/lib/sqlalchemy/orm/scoping.py
@@ -87,7 +87,8 @@ class scoped_session(object):
self.registry.clear()
def configure(self, **kwargs):
- """reconfigure the :class:`.sessionmaker` used by this :class:`.scoped_session`.
+ """reconfigure the :class:`.sessionmaker` used by this
+ :class:`.scoped_session`.
See :meth:`.sessionmaker.configure`.
@@ -142,27 +143,34 @@ class scoped_session(object):
ScopedSession = scoped_session
"""Old name for backwards compatibility."""
+
def instrument(name):
def do(self, *args, **kwargs):
return getattr(self.registry(), name)(*args, **kwargs)
return do
+
for meth in Session.public_methods:
setattr(scoped_session, meth, instrument(meth))
+
def makeprop(name):
def set(self, attr):
setattr(self.registry(), name, attr)
+
def get(self):
return getattr(self.registry(), name)
+
return property(get, set)
+
for prop in ('bind', 'dirty', 'deleted', 'new', 'identity_map',
- 'is_active', 'autoflush', 'no_autoflush'):
+ 'is_active', 'autoflush', 'no_autoflush'):
setattr(scoped_session, prop, makeprop(prop))
+
def clslevel(name):
def do(cls, *args, **kwargs):
return getattr(Session, name)(*args, **kwargs)
return classmethod(do)
+
for prop in ('close_all', 'object_session', 'identity_key'):
setattr(scoped_session, prop, clslevel(prop))
-