diff options
author | Brian Jarrett <celttechie@gmail.com> | 2014-07-14 12:38:04 -0600 |
---|---|---|
committer | Brian Jarrett <celttechie@gmail.com> | 2014-07-14 12:38:04 -0600 |
commit | f7ae07c767968bff776ad57d583a9caa916e122d (patch) | |
tree | d2cf63314038578d0bddf1197517461dd10adac2 | |
parent | 64f005309a0f1554ada3097d7a6e83aabc0f462e (diff) | |
download | sqlalchemy-pr/113.tar.gz |
Manual fixes for style E501, etc. errors in orm packagepr/113
25 files changed, 909 insertions, 752 deletions
diff --git a/lib/sqlalchemy/orm/__init__.py b/lib/sqlalchemy/orm/__init__.py index cd37920c6..741e79b9d 100644 --- a/lib/sqlalchemy/orm/__init__.py +++ b/lib/sqlalchemy/orm/__init__.py @@ -146,7 +146,8 @@ def backref(name, **kwargs): Used with the ``backref`` keyword argument to :func:`relationship` in place of a string argument, e.g.:: - 'items':relationship(SomeItem, backref=backref('parent', lazy='subquery')) + 'items':relationship( + SomeItem, backref=backref('parent', lazy='subquery')) """ return (name, kwargs) @@ -160,7 +161,8 @@ def deferred(*columns, **kw): :class:`.Column` object, however a collection is supported in order to support multiple columns mapped under the same attribute. - :param \**kw: additional keyword arguments passed to :class:`.ColumnProperty`. + :param \**kw: additional keyword arguments passed to + :class:`.ColumnProperty`. .. seealso:: @@ -198,14 +200,14 @@ def clear_mappers(): :func:`.clear_mappers` is *not* for normal use, as there is literally no valid usage for it outside of very specific testing scenarios. Normally, mappers are permanent structural components of user-defined classes, and - are never discarded independently of their class. If a mapped class itself - is garbage collected, its mapper is automatically disposed of as well. As - such, :func:`.clear_mappers` is only for usage in test suites that re-use - the same classes with different mappings, which is itself an extremely rare - use case - the only such use case is in fact SQLAlchemy's own test suite, - and possibly the test suites of other ORM extension libraries which - intend to test various combinations of mapper construction upon a fixed - set of classes. + are never discarded independently of their class. If a mapped class + itself is garbage collected, its mapper is automatically disposed of as + well. As such, :func:`.clear_mappers` is only for usage in test suites + that re-use the same classes with different mappings, which is itself an + extremely rare use case - the only such use case is in fact SQLAlchemy's + own test suite, and possibly the test suites of other ORM extension + libraries which intend to test various combinations of mapper construction + upon a fixed set of classes. """ mapperlib._CONFIGURE_MUTEX.acquire() diff --git a/lib/sqlalchemy/orm/attributes.py b/lib/sqlalchemy/orm/attributes.py index 6866eb45f..67e4dca9b 100644 --- a/lib/sqlalchemy/orm/attributes.py +++ b/lib/sqlalchemy/orm/attributes.py @@ -97,22 +97,23 @@ class QueryableAttribute(interfaces._MappedAttribute, * If the attribute is a :class:`.ColumnProperty` but is mapped to any other kind of SQL expression other than a :class:`.Column`, - the attribute will refer to the :attr:`.MapperProperty.info` dictionary - associated directly with the :class:`.ColumnProperty`, assuming the SQL - expression itself does not have its own ``.info`` attribute - (which should be the case, unless a user-defined SQL construct - has defined one). - - * If the attribute refers to any other kind of :class:`.MapperProperty`, - including :class:`.RelationshipProperty`, the attribute will refer - to the :attr:`.MapperProperty.info` dictionary associated with - that :class:`.MapperProperty`. - - * To access the :attr:`.MapperProperty.info` dictionary of the :class:`.MapperProperty` - unconditionally, including for a :class:`.ColumnProperty` that's - associated directly with a :class:`.schema.Column`, the attribute - can be referred to using :attr:`.QueryableAttribute.property` - attribute, as ``MyClass.someattribute.property.info``. + the attribute will refer to the :attr:`.MapperProperty.info` + dictionary associated directly with the :class:`.ColumnProperty`, + assuming the SQL expression itself does not have its own ``.info`` + attribute (which should be the case, unless a user-defined SQL + construct has defined one). + + * If the attribute refers to any other kind of + :class:`.MapperProperty`, including :class:`.RelationshipProperty`, + the attribute will refer to the :attr:`.MapperProperty.info` + dictionary associated with that :class:`.MapperProperty`. + + * To access the :attr:`.MapperProperty.info` dictionary of the + :class:`.MapperProperty` unconditionally, including for a + :class:`.ColumnProperty` that's associated directly with a + :class:`.schema.Column`, the attribute can be referred to using + :attr:`.QueryableAttribute.property` attribute, as + ``MyClass.someattribute.property.info``. .. versionadded:: 0.8.0 @@ -152,7 +153,8 @@ class QueryableAttribute(interfaces._MappedAttribute, def adapt_to_entity(self, adapt_to_entity): assert not self._of_type - return self.__class__(adapt_to_entity.entity, self.key, impl=self.impl, + return self.__class__(adapt_to_entity.entity, + self.key, impl=self.impl, comparator=self.comparator.adapt_to_entity( adapt_to_entity), parententity=adapt_to_entity) @@ -278,7 +280,9 @@ def create_proxied_attribute(descriptor): return self._comparator def adapt_to_entity(self, adapt_to_entity): - return self.__class__(adapt_to_entity.entity, self.key, self.descriptor, + return self.__class__(adapt_to_entity.entity, + self.key, + self.descriptor, self._comparator, adapt_to_entity) @@ -423,8 +427,8 @@ class AttributeImpl(object): for this key. send_modified_events - if False, the InstanceState._modified_event method will have no effect; - this means the attribute will never show up as changed in a + if False, the InstanceState._modified_event method will have no + effect; this means the attribute will never show up as changed in a history entry. """ self.class_ = class_ diff --git a/lib/sqlalchemy/orm/base.py b/lib/sqlalchemy/orm/base.py index f6e7143fd..a85f59f37 100644 --- a/lib/sqlalchemy/orm/base.py +++ b/lib/sqlalchemy/orm/base.py @@ -14,103 +14,128 @@ from ..sql import expression from . import exc import operator -PASSIVE_NO_RESULT = util.symbol('PASSIVE_NO_RESULT', - """Symbol returned by a loader callable or other attribute/history -retrieval operation when a value could not be determined, based -on loader callable flags. -""" - ) - -ATTR_WAS_SET = util.symbol('ATTR_WAS_SET', - """Symbol returned by a loader callable to indicate the -retrieved value, or values, were assigned to their attributes -on the target object. -""") - -ATTR_EMPTY = util.symbol('ATTR_EMPTY', - """Symbol used internally to indicate an attribute had no callable. -""") +PASSIVE_NO_RESULT = util.symbol( + 'PASSIVE_NO_RESULT', + """Symbol returned by a loader callable or other attribute/history + retrieval operation when a value could not be determined, based + on loader callable flags. + """ +) -NO_VALUE = util.symbol('NO_VALUE', - """Symbol which may be placed as the 'previous' value of an attribute, -indicating no value was loaded for an attribute when it was modified, -and flags indicated we were not to load it. -""" - ) +ATTR_WAS_SET = util.symbol( + 'ATTR_WAS_SET', + """Symbol returned by a loader callable to indicate the + retrieved value, or values, were assigned to their attributes + on the target object. + """ +) + +ATTR_EMPTY = util.symbol( + 'ATTR_EMPTY', + """Symbol used internally to indicate an attribute had no callable.""" +) + +NO_VALUE = util.symbol( + 'NO_VALUE', + """Symbol which may be placed as the 'previous' value of an attribute, + indicating no value was loaded for an attribute when it was modified, + and flags indicated we were not to load it. + """ +) -NEVER_SET = util.symbol('NEVER_SET', - """Symbol which may be placed as the 'previous' value of an attribute -indicating that the attribute had not been assigned to previously. -""" - ) - -NO_CHANGE = util.symbol("NO_CHANGE", - """No callables or SQL should be emitted on attribute access -and no state should change""", canonical=0 - ) - -CALLABLES_OK = util.symbol("CALLABLES_OK", - """Loader callables can be fired off if a value -is not present.""", canonical=1 - ) - -SQL_OK = util.symbol("SQL_OK", - """Loader callables can emit SQL at least on scalar value -attributes.""", canonical=2) - -RELATED_OBJECT_OK = util.symbol("RELATED_OBJECT_OK", - """callables can use SQL to load related objects as well -as scalar value attributes. -""", canonical=4 - ) - -INIT_OK = util.symbol("INIT_OK", - """Attributes should be initialized with a blank -value (None or an empty collection) upon get, if no other -value can be obtained. -""", canonical=8 - ) - -NON_PERSISTENT_OK = util.symbol("NON_PERSISTENT_OK", - """callables can be emitted if the parent is not persistent.""", - canonical=16 - ) - -LOAD_AGAINST_COMMITTED = util.symbol("LOAD_AGAINST_COMMITTED", - """callables should use committed values as primary/foreign keys during a load -""", canonical=32 - ) - -NO_AUTOFLUSH = util.symbol("NO_AUTOFLUSH", - """loader callables should disable autoflush. -""", canonical=64) +NEVER_SET = util.symbol( + 'NEVER_SET', + """Symbol which may be placed as the 'previous' value of an attribute + indicating that the attribute had not been assigned to previously. + """ +) + +NO_CHANGE = util.symbol( + "NO_CHANGE", + """No callables or SQL should be emitted on attribute access + and no state should change + """, canonical=0 +) + +CALLABLES_OK = util.symbol( + "CALLABLES_OK", + """Loader callables can be fired off if a value + is not present. + """, canonical=1 +) + +SQL_OK = util.symbol( + "SQL_OK", + """Loader callables can emit SQL at least on scalar value attributes.""", + canonical=2 +) + +RELATED_OBJECT_OK = util.symbol( + "RELATED_OBJECT_OK", + """Callables can use SQL to load related objects as well + as scalar value attributes. + """, canonical=4 +) + +INIT_OK = util.symbol( + "INIT_OK", + """Attributes should be initialized with a blank + value (None or an empty collection) upon get, if no other + value can be obtained. + """, canonical=8 +) + +NON_PERSISTENT_OK = util.symbol( + "NON_PERSISTENT_OK", + """Callables can be emitted if the parent is not persistent.""", + canonical=16 +) + +LOAD_AGAINST_COMMITTED = util.symbol( + "LOAD_AGAINST_COMMITTED", + """Callables should use committed values as primary/foreign keys during a + load. + """, canonical=32 +) + +NO_AUTOFLUSH = util.symbol( + "NO_AUTOFLUSH", + """Loader callables should disable autoflush.""", + canonical=64 +) # pre-packaged sets of flags used as inputs -PASSIVE_OFF = util.symbol("PASSIVE_OFF", - "Callables can be emitted in all cases.", - canonical=(RELATED_OBJECT_OK | NON_PERSISTENT_OK | - INIT_OK | CALLABLES_OK | SQL_OK) - ) -PASSIVE_RETURN_NEVER_SET = util.symbol("PASSIVE_RETURN_NEVER_SET", - """PASSIVE_OFF ^ INIT_OK""", - canonical=PASSIVE_OFF ^ INIT_OK - ) -PASSIVE_NO_INITIALIZE = util.symbol("PASSIVE_NO_INITIALIZE", - "PASSIVE_RETURN_NEVER_SET ^ CALLABLES_OK", - canonical=PASSIVE_RETURN_NEVER_SET ^ CALLABLES_OK - ) -PASSIVE_NO_FETCH = util.symbol("PASSIVE_NO_FETCH", - "PASSIVE_OFF ^ SQL_OK", - canonical=PASSIVE_OFF ^ SQL_OK - ) -PASSIVE_NO_FETCH_RELATED = util.symbol("PASSIVE_NO_FETCH_RELATED", - "PASSIVE_OFF ^ RELATED_OBJECT_OK", - canonical=PASSIVE_OFF ^ RELATED_OBJECT_OK - ) -PASSIVE_ONLY_PERSISTENT = util.symbol("PASSIVE_ONLY_PERSISTENT", - "PASSIVE_OFF ^ NON_PERSISTENT_OK", - canonical=PASSIVE_OFF ^ NON_PERSISTENT_OK - ) +PASSIVE_OFF = util.symbol( + "PASSIVE_OFF", + "Callables can be emitted in all cases.", + canonical=(RELATED_OBJECT_OK | NON_PERSISTENT_OK | + INIT_OK | CALLABLES_OK | SQL_OK) +) +PASSIVE_RETURN_NEVER_SET = util.symbol( + "PASSIVE_RETURN_NEVER_SET", + """PASSIVE_OFF ^ INIT_OK""", + canonical=PASSIVE_OFF ^ INIT_OK +) +PASSIVE_NO_INITIALIZE = util.symbol( + "PASSIVE_NO_INITIALIZE", + "PASSIVE_RETURN_NEVER_SET ^ CALLABLES_OK", + canonical=PASSIVE_RETURN_NEVER_SET ^ CALLABLES_OK +) +PASSIVE_NO_FETCH = util.symbol( + "PASSIVE_NO_FETCH", + "PASSIVE_OFF ^ SQL_OK", + canonical=PASSIVE_OFF ^ SQL_OK +) +PASSIVE_NO_FETCH_RELATED = util.symbol( + "PASSIVE_NO_FETCH_RELATED", + "PASSIVE_OFF ^ RELATED_OBJECT_OK", + canonical=PASSIVE_OFF ^ RELATED_OBJECT_OK +) +PASSIVE_ONLY_PERSISTENT = util.symbol( + "PASSIVE_ONLY_PERSISTENT", + "PASSIVE_OFF ^ NON_PERSISTENT_OK", + canonical=PASSIVE_OFF ^ NON_PERSISTENT_OK +) DEFAULT_MANAGER_ATTR = '_sa_class_manager' DEFAULT_STATE_ATTR = '_sa_instance_state' @@ -194,7 +219,9 @@ def state_str(state): def state_class_str(state): - """Return a string describing an instance's class via its InstanceState.""" + """Return a string describing an instance's class via its + InstanceState. + """ if state is None: return "None" @@ -275,7 +302,8 @@ def _class_to_mapper(class_or_mapper): def _mapper_or_none(entity): """Return the :class:`.Mapper` for the given class or None if the - class is not mapped.""" + class is not mapped. + """ insp = inspection.inspect(entity, False) if insp is not None: @@ -286,7 +314,8 @@ def _mapper_or_none(entity): def _is_mapped_class(entity): """Return True if the given object is a mapped class, - :class:`.Mapper`, or :class:`.AliasedClass`.""" + :class:`.Mapper`, or :class:`.AliasedClass`. + """ insp = inspection.inspect(entity, False) return insp is not None and \ diff --git a/lib/sqlalchemy/orm/collections.py b/lib/sqlalchemy/orm/collections.py index a2ead8267..698677a0b 100644 --- a/lib/sqlalchemy/orm/collections.py +++ b/lib/sqlalchemy/orm/collections.py @@ -536,9 +536,9 @@ class collection(object): def removes_return(): """Mark the method as removing an entity in the collection. - Adds "remove from collection" handling to the method. The return value - of the method, if any, is considered the value to remove. The method - arguments are not inspected:: + Adds "remove from collection" handling to the method. The return + value of the method, if any, is considered the value to remove. The + method arguments are not inspected:: @collection.removes_return() def pop(self): ... @@ -953,7 +953,8 @@ def _instrument_class(cls): def _instrument_membership_mutator(method, before, argument, after): - """Route method args and/or return value through the collection adapter.""" + """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))' if before: fn_args = list(util.flatten_iterator(inspect.getargspec(method)[0])) @@ -1147,8 +1148,8 @@ def _list_decorators(): def __iadd__(fn): def __iadd__(self, iterable): - # list.__iadd__ takes any iterable and seems to let TypeError raise - # as-is instead of returning NotImplemented + # list.__iadd__ takes any iterable and seems to let TypeError + # raise as-is instead of returning NotImplemented for value in iterable: self.append(value) return self diff --git a/lib/sqlalchemy/orm/dependency.py b/lib/sqlalchemy/orm/dependency.py index 26340900f..c1cf66f14 100644 --- a/lib/sqlalchemy/orm/dependency.py +++ b/lib/sqlalchemy/orm/dependency.py @@ -256,8 +256,8 @@ class DependencyProcessor(object): "Can't flush None value found in " "collection %s" % (self.prop, )) elif state is not None and \ - not self.mapper._canload(state, - allow_subtypes=not self.enable_typechecks): + not self.mapper._canload( + state, allow_subtypes=not self.enable_typechecks): if self.mapper._canload(state, allow_subtypes=True): raise exc.FlushError('Attempting to flush an item of type ' '%(x)s as a member of collection ' @@ -439,8 +439,8 @@ class OneToManyDP(DependencyProcessor): if should_null_fks: for child in history.unchanged: if child is not None: - uowcommit.register_object(child, - operation="delete", prop=self.prop) + uowcommit.register_object( + child, operation="delete", prop=self.prop) def presort_saves(self, uowcommit, states): children_added = uowcommit.memo(('children_added', self), set) @@ -472,8 +472,9 @@ class OneToManyDP(DependencyProcessor): operation='delete', prop=self.prop) elif self.hasparent(child) is False: - uowcommit.register_object(child, isdelete=True, - operation="delete", prop=self.prop) + 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( @@ -696,8 +697,9 @@ class ManyToOneDP(DependencyProcessor): for child in todelete: if child is None: continue - uowcommit.register_object(child, isdelete=True, - operation="delete", prop=self.prop) + uowcommit.register_object( + child, isdelete=True, + operation="delete", prop=self.prop) t = self.mapper.cascade_iterator('delete', child) for c, m, st_, dct_ in t: uowcommit.register_object( @@ -714,8 +716,9 @@ class ManyToOneDP(DependencyProcessor): if history: for child in history.deleted: if self.hasparent(child) is False: - uowcommit.register_object(child, isdelete=True, - operation="delete", prop=self.prop) + uowcommit.register_object( + child, isdelete=True, + operation="delete", prop=self.prop) t = self.mapper.cascade_iterator('delete', child) for c, m, st_, dct_ in t: @@ -865,8 +868,8 @@ class DetectKeySwitch(DependencyProcessor): if not issubclass(state.class_, self.parent.class_): continue dict_ = state.dict - related = state.get_impl(self.key).get(state, dict_, - passive=self._passive_update_flag) + related = state.get_impl(self.key).get( + state, dict_, passive=self._passive_update_flag) if related is not attributes.PASSIVE_NO_RESULT and \ related is not None: related_state = attributes.instance_state(dict_[self.key]) @@ -881,10 +884,8 @@ class DetectKeySwitch(DependencyProcessor): uowcommit, self.passive_updates) def _pks_changed(self, uowcommit, state): - return bool(state.key) and sync.source_modified(uowcommit, - state, - self.mapper, - self.prop.synchronize_pairs) + return bool(state.key) and sync.source_modified( + uowcommit, state, self.mapper, self.prop.synchronize_pairs) class ManyToManyDP(DependencyProcessor): @@ -975,8 +976,9 @@ class ManyToManyDP(DependencyProcessor): if history: for child in history.deleted: if self.hasparent(child) is False: - uowcommit.register_object(child, isdelete=True, - operation="delete", prop=self.prop) + uowcommit.register_object( + child, isdelete=True, + operation="delete", prop=self.prop) for c, m, st_, dct_ in self.mapper.cascade_iterator( 'delete', child): diff --git a/lib/sqlalchemy/orm/deprecated_interfaces.py b/lib/sqlalchemy/orm/deprecated_interfaces.py index abc7dfeeb..fa693c968 100644 --- a/lib/sqlalchemy/orm/deprecated_interfaces.py +++ b/lib/sqlalchemy/orm/deprecated_interfaces.py @@ -107,9 +107,10 @@ class MapperExtension(object): elif meth == 'init_failed': def go(ls_meth): def init_failed(instance, args, kwargs): - util.warn_exception(ls_meth, self, self.class_, - self.class_manager.original_init, - instance, args, kwargs) + util.warn_exception( + ls_meth, self, self.class_, + self.class_manager.original_init, + instance, args, kwargs) return init_failed event.listen(self.class_manager, 'init_failure', diff --git a/lib/sqlalchemy/orm/descriptor_props.py b/lib/sqlalchemy/orm/descriptor_props.py index 13af39a7b..5ed24b8c0 100644 --- a/lib/sqlalchemy/orm/descriptor_props.py +++ b/lib/sqlalchemy/orm/descriptor_props.py @@ -63,9 +63,8 @@ class DescriptorProperty(MapperProperty): fdel=fdel, ) - proxy_attr = attributes.\ - create_proxied_attribute(self.descriptor)\ - ( + proxy_attr = attributes.create_proxied_attribute( + self.descriptor)( self.parent.class_, self.key, self.descriptor, @@ -94,8 +93,8 @@ class CompositeProperty(DescriptorProperty): def __init__(self, class_, *attrs, **kwargs): """Return a composite column-based property for use with a Mapper. - See the mapping documentation section :ref:`mapper_composite` for a full - usage example. + See the mapping documentation section :ref:`mapper_composite` for a + full usage example. The :class:`.MapperProperty` returned by :func:`.composite` is the :class:`.CompositeProperty`. @@ -119,13 +118,14 @@ class CompositeProperty(DescriptorProperty): A group name for this property when marked as deferred. :param deferred: - When True, the column property is "deferred", meaning that it does not - load immediately, and is instead loaded when the attribute is first - accessed on an instance. See also :func:`~sqlalchemy.orm.deferred`. + When True, the column property is "deferred", meaning that it does + not load immediately, and is instead loaded when the attribute is + first accessed on an instance. See also + :func:`~sqlalchemy.orm.deferred`. :param comparator_factory: a class which extends - :class:`.CompositeProperty.Comparator` which provides custom SQL clause - generation for comparison operations. + :class:`.CompositeProperty.Comparator` which provides custom SQL + clause generation for comparison operations. :param doc: optional string that will be applied as the doc on the @@ -139,8 +139,8 @@ class CompositeProperty(DescriptorProperty): :param extension: an :class:`.AttributeExtension` instance, or list of extensions, which will be prepended to the list of - attribute listeners for the resulting descriptor placed on the class. - **Deprecated.** Please see :class:`.AttributeEvents`. + attribute listeners for the resulting descriptor placed on the + class. **Deprecated.** Please see :class:`.AttributeEvents`. """ @@ -241,7 +241,8 @@ class CompositeProperty(DescriptorProperty): props = [] for attr in self.attrs: if isinstance(attr, str): - prop = self.parent.get_property(attr, _configure_mappers=False) + prop = self.parent.get_property( + attr, _configure_mappers=False) elif isinstance(attr, schema.Column): prop = self.parent._columntoproperty[attr] elif isinstance(attr, attributes.InstrumentedAttribute): @@ -288,7 +289,7 @@ class CompositeProperty(DescriptorProperty): if k not in dict_: return - #assert self.key not in dict_ + # assert self.key not in dict_ dict_[self.key] = self.composite_class( *[state.dict[key] for key in self._attribute_keys] @@ -472,8 +473,8 @@ class ConcreteInheritedProperty(DescriptorProperty): def __init__(self): def warn(): raise AttributeError("Concrete %s does not implement " - "attribute %r at the instance level. Add this " - "property explicitly to %s." % + "attribute %r at the instance level. Add " + "this property explicitly to %s." % (self.parent, self.key, self.parent)) class NoninheritedConcreteProp(object): @@ -524,11 +525,11 @@ class SynonymProperty(DescriptorProperty): job_status = synonym("_job_status", map_column=True) The above class ``MyClass`` will now have the ``job_status`` - :class:`.Column` object mapped to the attribute named ``_job_status``, - and the attribute named ``job_status`` will refer to the synonym - itself. This feature is typically used in conjunction with the - ``descriptor`` argument in order to link a user-defined descriptor - as a "wrapper" for an existing column. + :class:`.Column` object mapped to the attribute named + ``_job_status``, and the attribute named ``job_status`` will refer + to the synonym itself. This feature is typically used in + conjunction with the ``descriptor`` argument in order to link a + user-defined descriptor as a "wrapper" for an existing column. :param comparator_factory: A subclass of :class:`.PropComparator` that will provide custom comparison behavior at the SQL expression @@ -647,7 +648,8 @@ class ComparableProperty(DescriptorProperty): 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) ) diff --git a/lib/sqlalchemy/orm/dynamic.py b/lib/sqlalchemy/orm/dynamic.py index ca0a59481..51db1b107 100644 --- a/lib/sqlalchemy/orm/dynamic.py +++ b/lib/sqlalchemy/orm/dynamic.py @@ -31,16 +31,17 @@ class DynaLoader(strategies.AbstractRelationshipLoader): "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, - uselist=True, - impl_class=DynamicAttributeImpl, - target_mapper=self.parent_property.mapper, - order_by=self.parent_property.order_by, - query_class=self.parent_property.query_class, - backref=self.parent_property.back_populates, - ) + strategies._register_attribute( + self, + mapper, + useobject=True, + uselist=True, + impl_class=DynamicAttributeImpl, + target_mapper=self.parent_property.mapper, + order_by=self.parent_property.order_by, + query_class=self.parent_property.query_class, + backref=self.parent_property.back_populates, + ) class DynamicAttributeImpl(attributes.AttributeImpl): @@ -65,8 +66,8 @@ class DynamicAttributeImpl(attributes.AttributeImpl): def get(self, state, dict_, passive=attributes.PASSIVE_OFF): if not passive & attributes.SQL_OK: - return self._get_collection_history(state, - attributes.PASSIVE_NO_INITIALIZE).added_items + return self._get_collection_history( + state, attributes.PASSIVE_NO_INITIALIZE).added_items else: return self.query_class(self, state) diff --git a/lib/sqlalchemy/orm/events.py b/lib/sqlalchemy/orm/events.py index f4fac7af7..aa99673ba 100644 --- a/lib/sqlalchemy/orm/events.py +++ b/lib/sqlalchemy/orm/events.py @@ -71,8 +71,9 @@ class InstrumentationEvents(event.Events): return fn(target_cls, *arg) def remove(ref): - key = event.registry._EventKey(None, identifier, listen, - instrumentation._instrumentation_factory) + key = event.registry._EventKey( + None, identifier, listen, + instrumentation._instrumentation_factory) getattr(instrumentation._instrumentation_factory.dispatch, identifier).remove(key) @@ -202,7 +203,8 @@ class InstanceEvents(event.Events): if propagate: for mgr in target.subclass_managers(True): - event_key.with_dispatch_target(mgr).base_listen(propagate=True) + event_key.with_dispatch_target(mgr).base_listen( + propagate=True) @classmethod def _clear(cls): @@ -390,9 +392,9 @@ class _EventsHold(event.RefCollection): collection = cls.all_holds[subclass] for event_key, raw, propagate in collection.values(): if propagate or subclass is class_: - # since we can't be sure in what order different classes - # in a hierarchy are triggered with populate(), - # we rely upon _EventsHold for all event + # since we can't be sure in what order different + # classes in a hierarchy are triggered with + # populate(), we rely upon _EventsHold for all event # assignment, instead of using the generic propagate # flag. event_key.with_dispatch_target(subject).\ @@ -1289,8 +1291,10 @@ class SessionEvents(event.Events): The :meth:`~.SessionEvents.before_commit` hook is *not* per-flush, that is, the :class:`.Session` can emit SQL to the database many times within the scope of a transaction. - For interception of these events, use the :meth:`~.SessionEvents.before_flush`, - :meth:`~.SessionEvents.after_flush`, or :meth:`~.SessionEvents.after_flush_postexec` + For interception of these events, use the + :meth:`~.SessionEvents.before_flush`, + :meth:`~.SessionEvents.after_flush`, or + :meth:`~.SessionEvents.after_flush_postexec` events. :param session: The target :class:`.Session`. @@ -1315,16 +1319,19 @@ class SessionEvents(event.Events): The :meth:`~.SessionEvents.after_commit` hook is *not* per-flush, that is, the :class:`.Session` can emit SQL to the database many times within the scope of a transaction. - For interception of these events, use the :meth:`~.SessionEvents.before_flush`, - :meth:`~.SessionEvents.after_flush`, or :meth:`~.SessionEvents.after_flush_postexec` + For interception of these events, use the + :meth:`~.SessionEvents.before_flush`, + :meth:`~.SessionEvents.after_flush`, or + :meth:`~.SessionEvents.after_flush_postexec` events. .. note:: The :class:`.Session` is not in an active transaction - when the :meth:`~.SessionEvents.after_commit` event is invoked, and therefore - can not emit SQL. To emit SQL corresponding to every transaction, - use the :meth:`~.SessionEvents.before_commit` event. + when the :meth:`~.SessionEvents.after_commit` event is invoked, + and therefore can not emit SQL. To emit SQL corresponding to + every transaction, use the :meth:`~.SessionEvents.before_commit` + event. :param session: The target :class:`.Session`. @@ -1472,8 +1479,8 @@ class SessionEvents(event.Events): This is called before an add, delete or merge causes the object to be part of the session. - .. versionadded:: 0.8. Note that :meth:`~.SessionEvents.after_attach` now - fires off after the item is part of the session. + .. versionadded:: 0.8. Note that :meth:`~.SessionEvents.after_attach` + now fires off after the item is part of the session. :meth:`.before_attach` is provided for those cases where the item should not yet be part of the session state. @@ -1521,8 +1528,8 @@ class SessionEvents(event.Events): details about the update, including these attributes: * ``session`` - the :class:`.Session` involved - * ``query`` -the :class:`.Query` object that this update operation was - called upon. + * ``query`` -the :class:`.Query` object that this update operation + was called upon. * ``context`` The :class:`.QueryContext` object, corresponding to the invocation of an ORM query. * ``result`` the :class:`.ResultProxy` returned as a result of the @@ -1547,8 +1554,8 @@ class SessionEvents(event.Events): details about the update, including these attributes: * ``session`` - the :class:`.Session` involved - * ``query`` -the :class:`.Query` object that this update operation was - called upon. + * ``query`` -the :class:`.Query` object that this update operation + was called upon. * ``context`` The :class:`.QueryContext` object, corresponding to the invocation of an ORM query. * ``result`` the :class:`.ResultProxy` returned as a result of the @@ -1678,8 +1685,9 @@ class AttributeEvents(event.Events): chained event propagation. .. versionchanged:: 0.9.0 the ``initiator`` argument is now - passed as a :class:`.attributes.Event` object, and may be modified - by backref handlers within a chain of backref-linked events. + passed as a :class:`.attributes.Event` object, and may be + modified by backref handlers within a chain of backref-linked + events. :return: if the event was registered with ``retval=True``, the given value, or a new effective value, should be returned. @@ -1699,8 +1707,9 @@ class AttributeEvents(event.Events): chained event propagation. .. versionchanged:: 0.9.0 the ``initiator`` argument is now - passed as a :class:`.attributes.Event` object, and may be modified - by backref handlers within a chain of backref-linked events. + passed as a :class:`.attributes.Event` object, and may be + modified by backref handlers within a chain of backref-linked + events. :return: No return value is defined for this event. """ @@ -1727,8 +1736,9 @@ class AttributeEvents(event.Events): chained event propagation. .. versionchanged:: 0.9.0 the ``initiator`` argument is now - passed as a :class:`.attributes.Event` object, and may be modified - by backref handlers within a chain of backref-linked events. + passed as a :class:`.attributes.Event` object, and may be + modified by backref handlers within a chain of backref-linked + events. :return: if the event was registered with ``retval=True``, the given value, or a new effective value, should be returned. diff --git a/lib/sqlalchemy/orm/instrumentation.py b/lib/sqlalchemy/orm/instrumentation.py index 5afa21888..f58b8807f 100644 --- a/lib/sqlalchemy/orm/instrumentation.py +++ b/lib/sqlalchemy/orm/instrumentation.py @@ -64,7 +64,7 @@ class ClassManager(dict): self.update(base) self.dispatch._events._new_classmanager_instance(class_, self) - #events._InstanceEventsHold.populate(class_, self) + # events._InstanceEventsHold.populate(class_, self) for basecls in class_.__mro__: mgr = manager_of_class(basecls) @@ -100,7 +100,8 @@ class ClassManager(dict): implement :class:`._InspectionAttr`. This includes :class:`.QueryableAttribute` as well as extension - types such as :class:`.hybrid_property` and :class:`.AssociationProxy`. + types such as :class:`.hybrid_property` and + :class:`.AssociationProxy`. """ if exclude is None: diff --git a/lib/sqlalchemy/orm/interfaces.py b/lib/sqlalchemy/orm/interfaces.py index 153b17d26..9bc1c3dd0 100644 --- a/lib/sqlalchemy/orm/interfaces.py +++ b/lib/sqlalchemy/orm/interfaces.py @@ -22,7 +22,8 @@ from __future__ import absolute_import from .. import exc as sa_exc, util, inspect from ..sql import operators from collections import deque -from .base import ONETOMANY, MANYTOONE, MANYTOMANY, EXT_CONTINUE, EXT_STOP, NOT_EXTENSION +from .base import (ONETOMANY, MANYTOONE, MANYTOMANY, + EXT_CONTINUE, EXT_STOP, NOT_EXTENSION) from .base import _InspectionAttr, _MappedAttribute from .path_registry import PathRegistry import collections diff --git a/lib/sqlalchemy/orm/loading.py b/lib/sqlalchemy/orm/loading.py index 91220ccf2..232eb89de 100644 --- a/lib/sqlalchemy/orm/loading.py +++ b/lib/sqlalchemy/orm/loading.py @@ -383,7 +383,7 @@ def instance_processor(mapper, context, path, adapter, state, dict_, mapper.version_id_col) != \ - row[version_id_col]: + row[version_id_col]: raise orm_exc.StaleDataError( "Instance '%s' has version id '%s' which " @@ -460,7 +460,8 @@ def instance_processor(mapper, context, path, adapter, if loaded_instance and load_evt: state.manager.dispatch.load(state, context) elif isnew and refresh_evt: - state.manager.dispatch.refresh(state, context, only_load_props) + state.manager.dispatch.refresh( + state, context, only_load_props) elif state in context.partials or state.unloaded or eager_populators: # state is having a partial set of its attributes @@ -557,7 +558,7 @@ def _configure_subclass_mapper(mapper, context, path, adapter): def load_scalar_attributes(mapper, state, attribute_names): """initiate a column-based attribute refresh operation.""" - #assert mapper is _state_mapper(state) + # assert mapper is _state_mapper(state) session = state.session if not session: raise orm_exc.DetachedInstanceError( diff --git a/lib/sqlalchemy/orm/mapper.py b/lib/sqlalchemy/orm/mapper.py index fcd7e18ac..7e5166393 100644 --- a/lib/sqlalchemy/orm/mapper.py +++ b/lib/sqlalchemy/orm/mapper.py @@ -214,13 +214,14 @@ class Mapper(_InspectionAttr): :param confirm_deleted_rows: defaults to True; when a DELETE occurs of one more rows based on specific primary keys, a warning is emitted when the number of rows matched does not equal the number - of rows expected. This parameter may be set to False to handle the case - where database ON DELETE CASCADE rules may be deleting some of those - rows automatically. The warning may be changed to an exception - in a future release. + of rows expected. This parameter may be set to False to handle the + case where database ON DELETE CASCADE rules may be deleting some of + those rows automatically. The warning may be changed to an + exception in a future release. - .. versionadded:: 0.9.4 - added :paramref:`.mapper.confirm_deleted_rows` - as well as conditional matched row checking on delete. + .. versionadded:: 0.9.4 - added + :paramref:`.mapper.confirm_deleted_rows` as well as conditional + matched row checking on delete. :param eager_defaults: if True, the ORM will immediately fetch the value of server-generated default values after an INSERT or UPDATE, @@ -230,8 +231,8 @@ class Mapper(_InspectionAttr): this scheme will emit an individual ``SELECT`` statement per row inserted or updated, which note can add significant performance overhead. However, if the - target database supports :term:`RETURNING`, the default values will be - returned inline with the INSERT or UPDATE statement, which can + target database supports :term:`RETURNING`, the default values will + be returned inline with the INSERT or UPDATE statement, which can greatly enhance performance for an application that needs frequent access to just-generated server defaults. @@ -269,10 +270,10 @@ class Mapper(_InspectionAttr): define how the two tables are joined; defaults to a natural join between the two tables. - :param inherit_foreign_keys: When ``inherit_condition`` is used and the - columns present are missing a :class:`.ForeignKey` configuration, - this parameter can be used to specify which columns are "foreign". - In most cases can be left as ``None``. + :param inherit_foreign_keys: When ``inherit_condition`` is used and + the columns present are missing a :class:`.ForeignKey` + configuration, this parameter can be used to specify which columns + are "foreign". In most cases can be left as ``None``. :param legacy_is_orphan: Boolean, defaults to ``False``. When ``True``, specifies that "legacy" orphan consideration @@ -280,12 +281,12 @@ class Mapper(_InspectionAttr): that a pending (that is, not persistent) object is auto-expunged from an owning :class:`.Session` only when it is de-associated from *all* parents that specify a ``delete-orphan`` cascade towards - this mapper. The new default behavior is that the object is auto-expunged - when it is de-associated with *any* of its parents that specify - ``delete-orphan`` cascade. This behavior is more consistent with - that of a persistent object, and allows behavior to be consistent - in more scenarios independently of whether or not an orphanable - object has been flushed yet or not. + this mapper. The new default behavior is that the object is + auto-expunged when it is de-associated with *any* of its parents + that specify ``delete-orphan`` cascade. This behavior is more + consistent with that of a persistent object, and allows behavior to + be consistent in more scenarios independently of whether or not an + orphanable object has been flushed yet or not. See the change note and example at :ref:`legacy_is_orphan_addition` for more detail on this change. @@ -296,9 +297,9 @@ class Mapper(_InspectionAttr): is expunged from the :class:`.Session` as soon as it is de-associated from any of its orphan-enabled parents. Previously, the pending object would be expunged only if de-associated - from all of its orphan-enabled parents. The new flag ``legacy_is_orphan`` - is added to :func:`.orm.mapper` which re-establishes the - legacy behavior. + from all of its orphan-enabled parents. The new flag + ``legacy_is_orphan`` is added to :func:`.orm.mapper` which + re-establishes the legacy behavior. :param non_primary: Specify that this :class:`.Mapper` is in addition to the "primary" mapper, that is, the one used for persistence. @@ -447,8 +448,8 @@ class Mapper(_InspectionAttr): based on all those :class:`.MapperProperty` instances declared in the declared class body. - :param primary_key: A list of :class:`.Column` objects which define the - primary key to be used against this mapper's selectable unit. + :param primary_key: A list of :class:`.Column` objects which define + the primary key to be used against this mapper's selectable unit. This is normally simply the primary key of the ``local_table``, but can be overridden here. @@ -478,13 +479,13 @@ class Mapper(_InspectionAttr): return next_version Alternatively, server-side versioning functions such as triggers, - or programmatic versioning schemes outside of the version id generator - may be used, by specifying the value ``False``. + or programmatic versioning schemes outside of the version id + generator may be used, by specifying the value ``False``. Please see :ref:`server_side_version_counter` for a discussion of important points when using this option. - .. versionadded:: 0.9.0 ``version_id_generator`` supports server-side - version number generation. + .. versionadded:: 0.9.0 ``version_id_generator`` supports + server-side version number generation. .. seealso:: @@ -505,7 +506,8 @@ class Mapper(_InspectionAttr): .. seealso:: - :ref:`with_polymorphic` - discussion of polymorphic querying techniques. + :ref:`with_polymorphic` - discussion of polymorphic querying + techniques. """ @@ -905,7 +907,7 @@ class Mapper(_InspectionAttr): self.local_table = self.inherits.local_table self.mapped_table = self.inherits.mapped_table self.single = True - elif not self.local_table is self.inherits.local_table: + elif self.local_table is not self.inherits.local_table: if self.concrete: self.mapped_table = self.local_table for mapper in self.iterate_to_root(): @@ -926,9 +928,10 @@ class Mapper(_InspectionAttr): self.inherit_condition) fks = util.to_set(self.inherit_foreign_keys) - self._inherits_equated_pairs = sql_util.criterion_as_pairs( - self.mapped_table.onclause, - consider_as_foreign_keys=fks) + self._inherits_equated_pairs = \ + sql_util.criterion_as_pairs( + self.mapped_table.onclause, + consider_as_foreign_keys=fks) else: self.mapped_table = self.local_table @@ -1375,8 +1378,7 @@ class Mapper(_InspectionAttr): if isinstance(col, schema.Column) and ( self.with_polymorphic is None or self.with_polymorphic[1]. - corresponding_column(col) is None - ): + corresponding_column(col) is None): raise sa_exc.InvalidRequestError( "Could not map polymorphic_on column " "'%s' to the mapped table - polymorphic " @@ -1441,8 +1443,10 @@ class Mapper(_InspectionAttr): if setter: def _set_polymorphic_identity(state): dict_ = state.dict - state.get_impl(polymorphic_key).set(state, dict_, - state.manager.mapper.polymorphic_identity, None) + state.get_impl(polymorphic_key).set( + state, dict_, + state.manager.mapper.polymorphic_identity, + None) def _validate_polymorphic_identity(mapper, state, dict_): if polymorphic_key in dict_ and \ @@ -1458,7 +1462,8 @@ class Mapper(_InspectionAttr): ) self._set_polymorphic_identity = _set_polymorphic_identity - self._validate_polymorphic_identity = _validate_polymorphic_identity + self._validate_polymorphic_identity = \ + _validate_polymorphic_identity else: self._set_polymorphic_identity = None @@ -1977,15 +1982,16 @@ class Mapper(_InspectionAttr): """A namespace of all :class:`._InspectionAttr` attributes associated with the mapped class. - These attributes are in all cases Python :term:`descriptors` associated - with the mapped class or its superclasses. + These attributes are in all cases Python :term:`descriptors` + associated with the mapped class or its superclasses. This namespace includes attributes that are mapped to the class as well as attributes declared by extension modules. It includes any Python descriptor type that inherits from - :class:`._InspectionAttr`. This includes :class:`.QueryableAttribute`, - as well as extension types such as :class:`.hybrid_property`, - :class:`.hybrid_method` and :class:`.AssociationProxy`. + :class:`._InspectionAttr`. This includes + :class:`.QueryableAttribute`, as well as extension types such as + :class:`.hybrid_property`, :class:`.hybrid_method` and + :class:`.AssociationProxy`. To distinguish between mapped attributes and extension attributes, the attribute :attr:`._InspectionAttr.extension_type` will refer @@ -1993,8 +1999,9 @@ class Mapper(_InspectionAttr): When dealing with a :class:`.QueryableAttribute`, the :attr:`.QueryableAttribute.property` attribute refers to the - :class:`.MapperProperty` property, which is what you get when referring - to the collection of mapped properties via :attr:`.Mapper.attrs`. + :class:`.MapperProperty` property, which is what you get when + referring to the collection of mapped properties via + :attr:`.Mapper.attrs`. .. versionadded:: 0.8.0 @@ -2235,11 +2242,11 @@ class Mapper(_InspectionAttr): """Return an identity-map key for use in storing/retrieving an item from the identity map. - :param row: A :class:`.RowProxy` instance. The columns which are mapped - by this :class:`.Mapper` should be locatable in the row, preferably - via the :class:`.Column` object directly (as is the case when a - :func:`.select` construct is executed), or via string names of the form - ``<tablename>_<colname>``. + :param row: A :class:`.RowProxy` instance. The columns which are + mapped by this :class:`.Mapper` should be locatable in the row, + preferably via the :class:`.Column` object directly (as is the case + when a :func:`.select` construct is executed), or via string names of + the form ``<tablename>_<colname>``. """ pk_cols = self.primary_key @@ -2306,8 +2313,9 @@ class Mapper(_InspectionAttr): for col in self.primary_key ] - def _get_state_attr_by_column(self, state, dict_, column, - passive=attributes.PASSIVE_RETURN_NEVER_SET): + def _get_state_attr_by_column( + self, state, dict_, column, + passive=attributes.PASSIVE_RETURN_NEVER_SET): prop = self._columntoproperty[column] return state.manager[prop.key].impl.get(state, dict_, passive=passive) @@ -2320,9 +2328,9 @@ class Mapper(_InspectionAttr): dict_ = attributes.instance_dict(obj) return self._get_committed_state_attr_by_column(state, dict_, column) - def _get_committed_state_attr_by_column(self, state, dict_, - column, - passive=attributes.PASSIVE_RETURN_NEVER_SET): + def _get_committed_state_attr_by_column( + self, state, dict_, column, + passive=attributes.PASSIVE_RETURN_NEVER_SET): prop = self._columntoproperty[column] return state.manager[prop.key].impl.\ @@ -2384,7 +2392,8 @@ class Mapper(_InspectionAttr): for mapper in reversed(list(self.iterate_to_root())): if mapper.local_table in tables: start = True - elif not isinstance(mapper.local_table, expression.TableClause): + elif not isinstance(mapper.local_table, + expression.TableClause): return None if start and not mapper.single: allconds.append(visitors.cloned_traverse( @@ -2435,8 +2444,9 @@ class Mapper(_InspectionAttr): prop = iterator.popleft() if type_ not in prop.cascade: continue - queue = deque(prop.cascade_iterator(type_, parent_state, - parent_dict, visited_states, halt_on)) + queue = deque(prop.cascade_iterator( + type_, parent_state, parent_dict, + visited_states, halt_on)) if queue: visitables.append((queue, mpp, None, None)) elif item_type is mpp: @@ -2519,7 +2529,8 @@ class Mapper(_InspectionAttr): if m._inherits_equated_pairs and \ cols.intersection( util.reduce(set.union, - [l.proxy_set for l, r in m._inherits_equated_pairs]) + [l.proxy_set for l, r in + m._inherits_equated_pairs]) ): result[table].append((m, m._inherits_equated_pairs)) diff --git a/lib/sqlalchemy/orm/path_registry.py b/lib/sqlalchemy/orm/path_registry.py index 1508c15ca..f10a125a8 100644 --- a/lib/sqlalchemy/orm/path_registry.py +++ b/lib/sqlalchemy/orm/path_registry.py @@ -210,7 +210,8 @@ class PropRegistry(PathRegistry): def _default_path_loader_key(self): return ("loader", self.parent.token( - "%s:%s" % (self.prop.strategy_wildcard_key, _DEFAULT_TOKEN) + "%s:%s" % (self.prop.strategy_wildcard_key, + _DEFAULT_TOKEN) ).path ) diff --git a/lib/sqlalchemy/orm/persistence.py b/lib/sqlalchemy/orm/persistence.py index 11ba8ceed..295d4a3d0 100644 --- a/lib/sqlalchemy/orm/persistence.py +++ b/lib/sqlalchemy/orm/persistence.py @@ -331,9 +331,10 @@ def _collect_update_commands(base_mapper, uowtransaction, # in a different table than the one # where the version_id_col is. for prop in mapper._columntoproperty.values(): - history = state.manager[prop.key].impl.get_history( - state, state_dict, - attributes.PASSIVE_NO_INITIALIZE) + history = ( + state.manager[prop.key].impl.get_history( + state, state_dict, + attributes.PASSIVE_NO_INITIALIZE)) if history.added: hasdata = True else: @@ -484,9 +485,10 @@ def _emit_update_statements(base_mapper, uowtransaction, type_=col.type)) if needs_version_id: - clause.clauses.append(mapper.version_id_col == - sql.bindparam(mapper.version_id_col._label, - type_=mapper.version_id_col.type)) + clause.clauses.append( + mapper.version_id_col == sql.bindparam( + mapper.version_id_col._label, + type_=mapper.version_id_col.type)) stmt = table.update(clause) if mapper.base_mapper.eager_defaults: @@ -603,7 +605,7 @@ def _emit_insert_statements(base_mapper, uowtransaction, prop = mapper_rec._columntoproperty[col] if state_dict.get(prop.key) is None: # TODO: would rather say: - #state_dict[prop.key] = pk + # state_dict[prop.key] = pk mapper_rec._set_state_attr_by_column( state, state_dict, diff --git a/lib/sqlalchemy/orm/properties.py b/lib/sqlalchemy/orm/properties.py index d3ac38595..62ea93fb3 100644 --- a/lib/sqlalchemy/orm/properties.py +++ b/lib/sqlalchemy/orm/properties.py @@ -39,12 +39,12 @@ class ColumnProperty(StrategizedProperty): Column-based properties can normally be applied to the mapper's ``properties`` dictionary using the :class:`.Column` element directly. - Use this function when the given column is not directly present within the - mapper's selectable; examples include SQL expressions, functions, and - scalar SELECT queries. + Use this function when the given column is not directly present within + the mapper's selectable; examples include SQL expressions, functions, + and scalar SELECT queries. - Columns that aren't present in the mapper's selectable won't be persisted - by the mapper and are effectively "read-only" attributes. + Columns that aren't present in the mapper's selectable won't be + persisted by the mapper and are effectively "read-only" attributes. :param \*cols: list of Column objects to be mapped. @@ -63,8 +63,8 @@ class ColumnProperty(StrategizedProperty): .. versionadded:: 0.6.6 :param comparator_factory: a class which extends - :class:`.ColumnProperty.Comparator` which provides custom SQL clause - generation for comparison operations. + :class:`.ColumnProperty.Comparator` which provides custom SQL + clause generation for comparison operations. :param group: a group name for this property when marked as deferred. diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py index b5374f457..c77b20b2f 100644 --- a/lib/sqlalchemy/orm/query.py +++ b/lib/sqlalchemy/orm/query.py @@ -717,10 +717,11 @@ class Query(object): Also note that while :meth:`~sqlalchemy.orm.query.Query.yield_per` will set the ``stream_results`` execution option to True, currently - this is only understood by :mod:`~sqlalchemy.dialects.postgresql.psycopg2` dialect - which will stream results using server side cursors instead of pre-buffer - all rows for this query. Other DBAPIs pre-buffer all rows before - making them available. + this is only understood by + :mod:`~sqlalchemy.dialects.postgresql.psycopg2` dialect which will + stream results using server side cursors instead of pre-buffer all + rows for this query. Other DBAPIs pre-buffer all rows before making + them available. """ self._yield_per = count @@ -1039,7 +1040,8 @@ class Query(object): self._set_entity_selectables(self._entities[l:]) @util.pending_deprecation("0.7", - ":meth:`.add_column` is superseded by :meth:`.add_columns`", + ":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 @@ -1323,7 +1325,8 @@ class Query(object): """apply a HAVING criterion to the query and return the newly resulting :class:`.Query`. - :meth:`~.Query.having` is used in conjunction with :meth:`~.Query.group_by`. + :meth:`~.Query.having` is used in conjunction with + :meth:`~.Query.group_by`. HAVING criterion makes it possible to use filters on aggregate functions like COUNT, SUM, AVG, MAX, and MIN, eg.:: @@ -1455,8 +1458,8 @@ class Query(object): Consider a mapping between two classes ``User`` and ``Address``, with a relationship ``User.addresses`` representing a collection - of ``Address`` objects associated with each ``User``. The most common - usage of :meth:`~.Query.join` is to create a JOIN along this + of ``Address`` objects associated with each ``User``. The most + common usage of :meth:`~.Query.join` is to create a JOIN along this relationship, using the ``User.addresses`` attribute as an indicator for how this should occur:: @@ -1682,8 +1685,8 @@ class Query(object): :ref:`ormtutorial_joins` in the ORM tutorial. - :ref:`inheritance_toplevel` for details on how :meth:`~.Query.join` - is used for inheritance relationships. + :ref:`inheritance_toplevel` for details on how + :meth:`~.Query.join` is used for inheritance relationships. :func:`.orm.join` - a standalone ORM-level join function, used internally by :meth:`.Query.join`, which in previous @@ -1871,11 +1874,14 @@ class Query(object): isinstance(right_mapper.mapped_table, expression.Join) ): for from_obj in self._from_obj or [l_info.selectable]: - if sql_util.selectables_overlap(l_info.selectable, from_obj) and \ - sql_util.selectables_overlap(from_obj, r_info.selectable): + if sql_util.selectables_overlap( + l_info.selectable, from_obj) and \ + sql_util.selectables_overlap( + from_obj, r_info.selectable): overlap = True break - elif sql_util.selectables_overlap(l_info.selectable, r_info.selectable): + elif sql_util.selectables_overlap(l_info.selectable, + r_info.selectable): overlap = True if overlap and l_info.selectable is r_info.selectable: @@ -1959,10 +1965,11 @@ class Query(object): # apply an adapter to all subsequent filter() calls # until reset_joinpoint() is called. if need_adapter: - self._filter_aliases = ORMAdapter(right, - equivalents=right_mapper and - right_mapper._equivalent_columns or {}, - chain_to=self._filter_aliases) + self._filter_aliases = ORMAdapter( + right, + equivalents=right_mapper and + right_mapper._equivalent_columns or {}, + chain_to=self._filter_aliases) # if the onclause is a ClauseElement, adapt it with any # adapters that are in place right now @@ -2626,10 +2633,11 @@ class Query(object): This method has several key caveats: - * The method does **not** offer in-Python cascading of relationships - it - is assumed that ON DELETE CASCADE/SET NULL/etc. is configured for any foreign key - references which require it, otherwise the database may emit an - integrity violation if foreign key references are being enforced. + * The method does **not** offer in-Python cascading of relationships + - it is assumed that ON DELETE CASCADE/SET NULL/etc. is configured + for any foreign key references which require it, otherwise the + database may emit an integrity violation if foreign key references + are being enforced. After the DELETE, dependent objects in the :class:`.Session` which were impacted by an ON DELETE may not contain the current @@ -2638,8 +2646,8 @@ class Query(object): which normally occurs upon :meth:`.Session.commit` or can be forced by using :meth:`.Session.expire_all`. Accessing an expired object whose row has been deleted will invoke a SELECT to locate the - row; when the row is not found, an :class:`~sqlalchemy.orm.exc.ObjectDeletedError` - is raised. + row; when the row is not found, an + :class:`~sqlalchemy.orm.exc.ObjectDeletedError` is raised. * The :meth:`.MapperEvents.before_delete` and :meth:`.MapperEvents.after_delete` @@ -2695,9 +2703,9 @@ class Query(object): This method has several key caveats: - * The method does **not** offer in-Python cascading of relationships - it - is assumed that ON UPDATE CASCADE is configured for any foreign key - references which require it, otherwise the database may emit an + * The method does **not** offer in-Python cascading of relationships + - it is assumed that ON UPDATE CASCADE is configured for any foreign + key references which require it, otherwise the database may emit an integrity violation if foreign key references are being enforced. After the UPDATE, dependent objects in the :class:`.Session` which @@ -2706,16 +2714,16 @@ class Query(object): which normally occurs upon :meth:`.Session.commit` or can be forced by using :meth:`.Session.expire_all`. - * As of 0.8, this method will support multiple table updates, as detailed - in :ref:`multi_table_updates`, and this behavior does extend to support - updates of joined-inheritance and other multiple table mappings. However, - the **join condition of an inheritance mapper is currently not - automatically rendered**. - Care must be taken in any multiple-table update to explicitly include - the joining condition between those tables, even in mappings where - this is normally automatic. - E.g. if a class ``Engineer`` subclasses ``Employee``, an UPDATE of the - ``Engineer`` local table using criteria against the ``Employee`` + * As of 0.8, this method will support multiple table updates, as + detailed in :ref:`multi_table_updates`, and this behavior does + extend to support updates of joined-inheritance and other multiple + table mappings. However, the **join condition of an inheritance + mapper is currently not automatically rendered**. + Care must be taken in any multiple-table update to explicitly + include the joining condition between those tables, even in mappings + where this is normally automatic. + E.g. if a class ``Engineer`` subclasses ``Employee``, an UPDATE of + the ``Engineer`` local table using criteria against the ``Employee`` local table might look like:: session.query(Engineer).\\ @@ -3022,9 +3030,9 @@ class _MapperEntity(_QueryEntity): self._polymorphic_discriminator = polymorphic_on self.selectable = from_obj - query._mapper_loads_polymorphically_with(self.mapper, - sql_util.ColumnAdapter(from_obj, - self.mapper._equivalent_columns)) + query._mapper_loads_polymorphically_with( + self.mapper, sql_util.ColumnAdapter( + from_obj, self.mapper._equivalent_columns)) filter_fn = id @@ -3191,7 +3199,8 @@ class Bundle(object): bn = Bundle("mybundle", MyClass.x, MyClass.y) - for row in session.query(bn).filter(bn.c.x == 5).filter(bn.c.y == 4): + for row in session.query(bn).filter( + bn.c.x == 5).filter(bn.c.y == 4): print(row.mybundle.x, row.mybundle.y) :param name: name of the bundle. @@ -3224,7 +3233,8 @@ class Bundle(object): Bundle('b3', MyClass.x, MyClass.y) ) - q = sess.query(b1).filter(b1.c.b2.c.a == 5).filter(b1.c.b3.c.y == 9) + q = sess.query(b1).filter( + b1.c.b2.c.a == 5).filter(b1.c.b3.c.y == 9) .. seealso:: @@ -3265,7 +3275,8 @@ class Bundle(object): """ def proc(row, result): - return util.KeyedTuple([proc(row, None) for proc in procs], labels) + return util.KeyedTuple( + [proc(row, None) for proc in procs], labels) return proc @@ -3317,9 +3328,9 @@ class _BundleEntity(_QueryEntity): def adapt_to_selectable(self, query, sel): c = _BundleEntity(query, self.bundle, setup_entities=False) - #c._label_name = self._label_name - #c.entity_zero = self.entity_zero - #c.entities = self.entities + # c._label_name = self._label_name + # c.entity_zero = self.entity_zero + # c.entities = self.entities for ent in self._entities: ent.adapt_to_selectable(c, sel) diff --git a/lib/sqlalchemy/orm/relationships.py b/lib/sqlalchemy/orm/relationships.py index 90e3085a0..c2debda03 100644 --- a/lib/sqlalchemy/orm/relationships.py +++ b/lib/sqlalchemy/orm/relationships.py @@ -25,7 +25,8 @@ from ..sql.util import ( _deep_deannotate, selectables_overlap ) from ..sql import operators, expression, visitors -from .interfaces import MANYTOMANY, MANYTOONE, ONETOMANY, StrategizedProperty, PropComparator +from .interfaces import (MANYTOMANY, MANYTOONE, ONETOMANY, + StrategizedProperty, PropComparator) from ..inspection import inspect from . import mapper as mapperlib import collections @@ -116,8 +117,9 @@ class RelationshipProperty(StrategizedProperty): info=None): """Provide a relationship between two mapped classes. - This corresponds to a parent-child or associative table relationship. The - constructed class is an instance of :class:`.RelationshipProperty`. + This corresponds to a parent-child or associative table relationship. + The constructed class is an instance of + :class:`.RelationshipProperty`. A typical :func:`.relationship`, used in a classical mapping:: @@ -128,10 +130,11 @@ class RelationshipProperty(StrategizedProperty): 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 - if ``Child`` is declared below ``Parent`` in the same file:: + 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={ "children":relationship(lambda: Child, @@ -139,12 +142,12 @@ class RelationshipProperty(StrategizedProperty): }) When using the :ref:`declarative_toplevel` extension, the Declarative - initializer allows string arguments to be passed to :func:`.relationship`. - 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:: + initializer allows string arguments to be passed to + :func:`.relationship`. 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:: from sqlalchemy.ext.declarative import declarative_base @@ -157,18 +160,18 @@ class RelationshipProperty(StrategizedProperty): .. seealso:: - :ref:`relationship_config_toplevel` - Full introductory and reference - documentation for :func:`.relationship`. + :ref:`relationship_config_toplevel` - Full introductory and + reference documentation for :func:`.relationship`. :ref:`orm_tutorial_relationship` - ORM tutorial introduction. :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. - :paramref:`~.relationship.argument` may also be passed as a callable function - which is evaluated at mapper initialization time, and may be passed as a - Python-evaluable string when using Declarative. + :paramref:`~.relationship.argument` may also be passed as a callable + function which is evaluated at mapper initialization time, and may + be passed as a Python-evaluable string when using Declarative. .. seealso:: @@ -188,35 +191,37 @@ class RelationshipProperty(StrategizedProperty): present in the :class:`.MetaData` collection associated with the parent-mapped :class:`.Table`. - The :paramref:`~.relationship.secondary` keyword argument is typically - applied in the case where the intermediary :class:`.Table` is not - otherwise exprssed in any direct class mapping. If the "secondary" table - is also explicitly mapped elsewhere - (e.g. as in :ref:`association_pattern`), one should consider applying - the :paramref:`~.relationship.viewonly` flag so that this :func:`.relationship` - is not used for persistence operations which may conflict with those - of the association object pattern. + The :paramref:`~.relationship.secondary` keyword argument is + typically applied in the case where the intermediary :class:`.Table` + is not otherwise exprssed in any direct class mapping. If the + "secondary" table is also explicitly mapped elsewhere (e.g. as in + :ref:`association_pattern`), one should consider applying the + :paramref:`~.relationship.viewonly` flag so that this + :func:`.relationship` is not used for persistence operations which + may conflict with those of the association object pattern. .. seealso:: - :ref:`relationships_many_to_many` - Reference example of "many to many". + :ref:`relationships_many_to_many` - Reference example of "many + to many". :ref:`orm_tutorial_many_to_many` - ORM tutorial introduction to many-to-many relationships. - :ref:`self_referential_many_to_many` - Specifics on using many-to-many - in a self-referential case. + :ref:`self_referential_many_to_many` - Specifics on using + many-to-many in a self-referential case. :ref:`declarative_many_to_many` - Additional options when using Declarative. - :ref:`association_pattern` - an alternative to :paramref:`~.relationship.secondary` - when composing association table relationships, allowing additional - attributes to be specified on the association table. + :ref:`association_pattern` - an alternative to + :paramref:`~.relationship.secondary` when composing association + table relationships, allowing additional attributes to be + specified on the association table. - :ref:`composite_secondary_join` - a lesser-used pattern which in some - cases can enable complex :func:`.relationship` SQL conditions - to be used. + :ref:`composite_secondary_join` - a lesser-used pattern which + in some cases can enable complex :func:`.relationship` SQL + conditions to be used. .. versionadded:: 0.9.2 :paramref:`~.relationship.secondary` works more effectively when referring to a :class:`.Join` instance. @@ -252,11 +257,13 @@ class RelationshipProperty(StrategizedProperty): :param back_populates: - Takes a string name and has the same meaning as :paramref:`~.relationship.backref`, - except the complementing property is **not** created automatically, - and instead must be configured explicitly on the other mapper. The - complementing property should also indicate :paramref:`~.relationship.back_populates` - to this relationship to ensure proper functioning. + Takes a string name and has the same meaning as + :paramref:`~.relationship.backref`, except the complementing + property is **not** created automatically, and instead must be + configured explicitly on the other mapper. The complementing + property should also indicate + :paramref:`~.relationship.back_populates` to this relationship to + ensure proper functioning. .. seealso:: @@ -310,8 +317,9 @@ class RelationshipProperty(StrategizedProperty): examples. :param comparator_factory: - a class which extends :class:`.RelationshipProperty.Comparator` which - provides custom SQL clause generation for comparison operations. + a class which extends :class:`.RelationshipProperty.Comparator` + which provides custom SQL clause generation for comparison + operations. .. seealso:: @@ -326,20 +334,21 @@ class RelationshipProperty(StrategizedProperty): keyword to the innermost SELECT statement. When left as ``None``, the DISTINCT keyword will be applied in those cases when the target columns do not comprise the full primary key of the target table. - When set to ``True``, the DISTINCT keyword is applied to the innermost - SELECT unconditionally. + When set to ``True``, the DISTINCT keyword is applied to the + innermost SELECT unconditionally. It may be desirable to set this flag to False when the DISTINCT is reducing performance of the innermost subquery beyond that of what duplicate innermost rows may be causing. - .. versionadded:: 0.8.3 - :paramref:`~.relationship.distinct_target_key` - allows the + .. versionadded:: 0.8.3 - + :paramref:`~.relationship.distinct_target_key` allows the subquery eager loader to apply a DISTINCT modifier to the innermost SELECT. - .. versionchanged:: 0.9.0 - :paramref:`~.relationship.distinct_target_key` - now defaults to ``None``, so that the feature enables itself automatically for + .. versionchanged:: 0.9.0 - + :paramref:`~.relationship.distinct_target_key` now defaults to + ``None``, so that the feature enables itself automatically for those cases where the innermost query targets a non-unique key. @@ -388,8 +397,9 @@ class RelationshipProperty(StrategizedProperty): .. versionchanged:: 0.8 A multiple-foreign key join ambiguity can be resolved by - setting the :paramref:`~.relationship.foreign_keys` parameter alone, without the - need to explicitly set :paramref:`~.relationship.primaryjoin` as well. + setting the :paramref:`~.relationship.foreign_keys` + parameter alone, without the need to explicitly set + :paramref:`~.relationship.primaryjoin` as well. 2. The :class:`.Table` being mapped does not actually have :class:`.ForeignKey` or :class:`.ForeignKeyConstraint` @@ -397,10 +407,11 @@ class RelationshipProperty(StrategizedProperty): was reflected from a database that does not support foreign key reflection (MySQL MyISAM). - 3. The :paramref:`~.relationship.primaryjoin` argument is used to construct a non-standard - join condition, which makes use of columns or expressions that do - not normally refer to their "parent" column, such as a join condition - expressed by a complex comparison using a SQL function. + 3. The :paramref:`~.relationship.primaryjoin` argument is used to + construct a non-standard join condition, which makes use of + columns or expressions that do not normally refer to their + "parent" column, such as a join condition expressed by a + complex comparison using a SQL function. The :func:`.relationship` construct will raise informative error messages that suggest the use of the @@ -410,9 +421,10 @@ class RelationshipProperty(StrategizedProperty): :paramref:`~.relationship.foreign_keys` parameter is usually not needed. - :paramref:`~.relationship.foreign_keys` may also be passed as a callable function - which is evaluated at mapper initialization time, and may be passed as a - Python-evaluable string when using Declarative. + :paramref:`~.relationship.foreign_keys` may also be passed as a + callable function which is evaluated at mapper initialization time, + and may be passed as a Python-evaluable string when using + Declarative. .. seealso:: @@ -420,14 +432,16 @@ class RelationshipProperty(StrategizedProperty): :ref:`relationship_custom_foreign` - :func:`.foreign` - allows direct annotation of the "foreign" columns - within a :paramref:`~.relationship.primaryjoin` condition. + :func:`.foreign` - allows direct annotation of the "foreign" + columns within a :paramref:`~.relationship.primaryjoin` condition. .. versionadded:: 0.8 The :func:`.foreign` annotation can also be applied - directly to the :paramref:`~.relationship.primaryjoin` expression, which is an alternate, - more specific system of describing which columns in a particular - :paramref:`~.relationship.primaryjoin` should be considered "foreign". + directly to the :paramref:`~.relationship.primaryjoin` + expression, which is an alternate, more specific system of + describing which columns in a particular + :paramref:`~.relationship.primaryjoin` should be considered + "foreign". :param info: Optional data dictionary which will be populated into the :attr:`.MapperProperty.info` attribute of this object. @@ -441,18 +455,19 @@ class RelationshipProperty(StrategizedProperty): generally perform better than outer joins. This flag can be set to ``True`` when the relationship references an - object via many-to-one using local foreign keys that are not nullable, - or when the reference is one-to-one or a collection that is guaranteed - to have one or at least one entry. + object via many-to-one using local foreign keys that are not + nullable, or when the reference is one-to-one or a collection that + is guaranteed to have one or at least one entry. - If the joined-eager load is chained onto an existing LEFT OUTER JOIN, - ``innerjoin=True`` will be bypassed and the join will continue to - chain as LEFT OUTER JOIN so that the results don't change. As an alternative, - specify the value ``"nested"``. This will instead nest the join - on the right side, e.g. using the form "a LEFT OUTER JOIN (b JOIN c)". + If the joined-eager load is chained onto an existing LEFT OUTER + JOIN, ``innerjoin=True`` will be bypassed and the join will continue + to chain as LEFT OUTER JOIN so that the results don't change. As an + alternative, specify the value ``"nested"``. This will instead nest + the join on the right side, e.g. using the form "a LEFT OUTER JOIN + (b JOIN c)". - .. versionadded:: 0.9.4 Added ``innerjoin="nested"`` option to support - nesting of eager "inner" joins. + .. versionadded:: 0.9.4 Added ``innerjoin="nested"`` option to + support nesting of eager "inner" joins. .. seealso:: @@ -480,8 +495,8 @@ class RelationshipProperty(StrategizedProperty): how the related items should be loaded. Default value is ``select``. Values include: - * ``select`` - items should be loaded lazily when the property is first - accessed, using a separate SELECT statement, or identity map + * ``select`` - items should be loaded lazily when the property is + first accessed, using a separate SELECT statement, or identity map fetch for simple many-to-one references. * ``immediate`` - items should be loaded as the parents are loaded, @@ -494,8 +509,9 @@ class RelationshipProperty(StrategizedProperty): :paramref:`~.relationship.innerjoin` parameter. * ``subquery`` - items should be loaded "eagerly" as the parents are - loaded, using one additional SQL statement, which issues a JOIN to a - subquery of the original statement, for each collection requested. + loaded, using one additional SQL statement, which issues a JOIN to + a subquery of the original statement, for each collection + requested. * ``noload`` - no loading should occur at any time. This is to support "write-only" attributes, or attributes which are @@ -524,35 +540,35 @@ class RelationshipProperty(StrategizedProperty): Indicates loading behavior for transient or pending parent objects. When set to ``True``, causes the lazy-loader to - issue a query for a parent object that is not persistent, meaning it has - never been flushed. This may take effect for a pending object when - autoflush is disabled, or for a transient object that has been + issue a query for a parent object that is not persistent, meaning it + has never been flushed. This may take effect for a pending object + when autoflush is disabled, or for a transient object that has been "attached" to a :class:`.Session` but is not part of its pending collection. - The :paramref:`~.relationship.load_on_pending` flag does not improve behavior - when the ORM is used normally - object references should be constructed - at the object level, not at the foreign key level, so that they - are present in an ordinary way before a flush proceeds. This flag - is not not intended for general use. + The :paramref:`~.relationship.load_on_pending` flag does not improve + behavior when the ORM is used normally - object references should be + constructed at the object level, not at the foreign key level, so + that they are present in an ordinary way before a flush proceeds. + This flag is not not intended for general use. .. seealso:: - :meth:`.Session.enable_relationship_loading` - this method establishes - "load on pending" behavior for the whole object, and also allows - loading on objects that remain transient or detached. + :meth:`.Session.enable_relationship_loading` - this method + establishes "load on pending" behavior for the whole object, and + also allows loading on objects that remain transient or + detached. :param order_by: indicates the ordering that should be applied when loading these - items. :paramref:`~.relationship.order_by` is expected to refer to one - of the :class:`.Column` - objects to which the target class is mapped, or - the attribute itself bound to the target class which refers - to the column. + items. :paramref:`~.relationship.order_by` is expected to refer to + one of the :class:`.Column` objects to which the target class is + mapped, or the attribute itself bound to the target class which + refers to the column. - :paramref:`~.relationship.order_by` may also be passed as a callable function - which is evaluated at mapper initialization time, and may be passed as a - Python-evaluable string when using Declarative. + :paramref:`~.relationship.order_by` may also be passed as a callable + function which is evaluated at mapper initialization time, and may + be passed as a Python-evaluable string when using Declarative. :param passive_deletes=False: Indicates loading behavior during delete operations. @@ -641,12 +657,13 @@ class RelationshipProperty(StrategizedProperty): join of this child object against the parent object, or in a many-to-many relationship the join of the primary object to the association table. By default, this value is computed based on the - foreign key relationships of the parent and child tables (or association - table). + foreign key relationships of the parent and child tables (or + association table). - :paramref:`~.relationship.primaryjoin` may also be passed as a callable function - which is evaluated at mapper initialization time, and may be passed as a - Python-evaluable string when using Declarative. + :paramref:`~.relationship.primaryjoin` may also be passed as a + callable function which is evaluated at mapper initialization time, + and may be passed as a Python-evaluable string when using + Declarative. .. seealso:: @@ -656,15 +673,16 @@ class RelationshipProperty(StrategizedProperty): used for self-referential relationships, indicates the column or list of columns that form the "remote side" of the relationship. - :paramref:`.relationship.remote_side` may also be passed as a callable function - which is evaluated at mapper initialization time, and may be passed as a - Python-evaluable string when using Declarative. + :paramref:`.relationship.remote_side` may also be passed as a + callable function which is evaluated at mapper initialization time, + and may be passed as a Python-evaluable string when using + Declarative. .. versionchanged:: 0.8 The :func:`.remote` annotation can also be applied - directly to the ``primaryjoin`` expression, which is an alternate, - more specific system of describing which columns in a particular - ``primaryjoin`` should be considered "remote". + directly to the ``primaryjoin`` expression, which is an + alternate, more specific system of describing which columns in a + particular ``primaryjoin`` should be considered "remote". .. seealso:: @@ -672,8 +690,8 @@ class RelationshipProperty(StrategizedProperty): :paramref:`~.relationship.remote_side` is used to configure self-referential relationships. - :func:`.remote` - an annotation function that accomplishes the same - purpose as :paramref:`~.relationship.remote_side`, typically + :func:`.remote` - an annotation function that accomplishes the + same purpose as :paramref:`~.relationship.remote_side`, typically when a custom :paramref:`~.relationship.primaryjoin` condition is used. @@ -686,18 +704,19 @@ class RelationshipProperty(StrategizedProperty): .. seealso:: - :ref:`dynamic_relationship` - Introduction to "dynamic" relationship - loaders. + :ref:`dynamic_relationship` - Introduction to "dynamic" + relationship loaders. :param secondaryjoin: a SQL expression that will be used as the join of an association table to the child object. By default, this value is - computed based on the foreign key relationships of the association and - child tables. + computed based on the foreign key relationships of the association + and child tables. - :paramref:`~.relationship.secondaryjoin` may also be passed as a callable function - which is evaluated at mapper initialization time, and may be passed as a - Python-evaluable string when using Declarative. + :paramref:`~.relationship.secondaryjoin` may also be passed as a + callable function which is evaluated at mapper initialization time, + and may be passed as a Python-evaluable string when using + Declarative. .. seealso:: @@ -710,9 +729,9 @@ class RelationshipProperty(StrategizedProperty): should be treated either as one-to-one or one-to-many. Its usage is optional, except for :func:`.relationship` constructs which are many-to-one or many-to-many and also - specify the ``delete-orphan`` cascade option. The :func:`.relationship` - construct itself will raise an error instructing when this option - is required. + specify the ``delete-orphan`` cascade option. The + :func:`.relationship` construct itself will raise an error + instructing when this option is required. .. seealso:: @@ -727,33 +746,35 @@ class RelationshipProperty(StrategizedProperty): of the relationship - one to many forms a list, many to one forms a scalar, many to many is a list. If a scalar is desired where normally a list would be present, such as a bi-directional - one-to-one relationship, set :paramref:`~.relationship.uselist` to False. + one-to-one relationship, set :paramref:`~.relationship.uselist` to + False. The :paramref:`~.relationship.uselist` flag is also available on an - existing :func:`.relationship` construct as a read-only attribute, which - can be used to determine if this :func:`.relationship` deals with - collections or scalar attributes:: + existing :func:`.relationship` construct as a read-only attribute, + which can be used to determine if this :func:`.relationship` deals + with collections or scalar attributes:: >>> User.addresses.property.uselist True .. seealso:: - :ref:`relationships_one_to_one` - Introduction to the "one to one" - relationship pattern, which is typically when the + :ref:`relationships_one_to_one` - Introduction to the "one to + one" relationship pattern, which is typically when the :paramref:`~.relationship.uselist` flag is needed. :param viewonly=False: when set to True, the relationship is used only for loading objects, and not for any persistence operation. A :func:`.relationship` which specifies :paramref:`~.relationship.viewonly` can work - with a wider range of SQL operations within the :paramref:`~.relationship.primaryjoin` - condition, including operations that feature the use of - a variety of comparison operators as well as SQL functions such - as :func:`~.sql.expression.cast`. The :paramref:`~.relationship.viewonly` - flag is also of general use when defining any kind of :func:`~.relationship` - that doesn't represent the full set of related objects, to prevent - modifications of the collection from resulting in persistence operations. + with a wider range of SQL operations within the + :paramref:`~.relationship.primaryjoin` condition, including + operations that feature the use of a variety of comparison operators + as well as SQL functions such as :func:`~.sql.expression.cast`. The + :paramref:`~.relationship.viewonly` flag is also of general use when + defining any kind of :func:`~.relationship` that doesn't represent + the full set of related objects, to prevent modifications of the + collection from resulting in persistence operations. """ @@ -828,8 +849,8 @@ class RelationshipProperty(StrategizedProperty): """Produce boolean, comparison, and other operators for :class:`.RelationshipProperty` attributes. - See the documentation for :class:`.PropComparator` for a brief overview - of ORM level operator definition. + See the documentation for :class:`.PropComparator` for a brief + overview of ORM level operator definition. See also: @@ -922,8 +943,9 @@ class RelationshipProperty(StrategizedProperty): """ raise NotImplementedError('in_() not yet supported for ' - 'relationships. For a simple many-to-one, use ' - 'in_() against the set of foreign key values.') + 'relationships. For a simple ' + 'many-to-one, use in_() against ' + 'the set of foreign key values.') __hash__ = None @@ -971,19 +993,21 @@ class RelationshipProperty(StrategizedProperty): return _orm_annotate(self.property._optimized_compare( None, adapt_source=self.adapter)) elif self.property.uselist: - raise sa_exc.InvalidRequestError("Can't compare a colle" - "ction to an object or collection; use " - "contains() to test for membership.") + raise sa_exc.InvalidRequestError( + "Can't compare a collection to an object or collection; " + "use contains() to test for membership.") else: - return _orm_annotate(self.property._optimized_compare(other, - adapt_source=self.adapter)) + return _orm_annotate( + self.property._optimized_compare( + other, adapt_source=self.adapter)) def _criterion_exists(self, criterion=None, **kwargs): if getattr(self, '_of_type', None): info = inspect(self._of_type) target_mapper, to_selectable, is_aliased_class = \ info.mapper, info.selectable, info.is_aliased_class - if self.property._is_self_referential and not is_aliased_class: + if self.property._is_self_referential and not \ + is_aliased_class: to_selectable = to_selectable.alias() single_crit = target_mapper._single_table_criterion @@ -1002,9 +1026,10 @@ class RelationshipProperty(StrategizedProperty): source_selectable = None pj, sj, source, dest, secondary, target_adapter = \ - self.property._create_joins(dest_polymorphic=True, - dest_selectable=to_selectable, - source_selectable=source_selectable) + self.property._create_joins( + dest_polymorphic=True, + dest_selectable=to_selectable, + source_selectable=source_selectable) for k in kwargs: crit = getattr(self.property.mapper.class_, k) == kwargs[k] @@ -1021,7 +1046,8 @@ class RelationshipProperty(StrategizedProperty): else: j = _orm_annotate(pj, exclude=self.property.remote_side) - if criterion is not None and target_adapter and not is_aliased_class: + if criterion is not None and target_adapter and not \ + is_aliased_class: # limit this adapter to annotated only? criterion = target_adapter.traverse(criterion) @@ -1184,8 +1210,8 @@ class RelationshipProperty(StrategizedProperty): raise sa_exc.InvalidRequestError( "'contains' not implemented for scalar " "attributes. Use ==") - clause = self.property._optimized_compare(other, - adapt_source=self.adapter) + clause = self.property._optimized_compare( + other, adapt_source=self.adapter) if self.property.secondaryjoin is not None: clause.negation_clause = \ @@ -1199,8 +1225,10 @@ class RelationshipProperty(StrategizedProperty): 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)) + return sql.bindparam( + x, unique=True, callable_=lambda: + self.property.mapper. + _get_committed_attr_by_column(o, col)) def adapt(col): if self.adapter: @@ -1270,9 +1298,10 @@ class RelationshipProperty(StrategizedProperty): else: return self._criterion_exists() elif self.property.uselist: - raise sa_exc.InvalidRequestError("Can't compare a collection" - " to an object or collection; use " - "contains() to test for membership.") + raise sa_exc.InvalidRequestError( + "Can't compare a collection" + " to an object or collection; use " + "contains() to test for membership.") else: return self.__negated_contains_or_equals(other) @@ -1290,13 +1319,15 @@ class RelationshipProperty(StrategizedProperty): if self.uselist: return ~sql.exists([1], self.primaryjoin) else: - return self._optimized_compare(None, - value_is_parent=value_is_parent, - alias_secondary=alias_secondary) + return self._optimized_compare( + None, + value_is_parent=value_is_parent, + alias_secondary=alias_secondary) else: - return self._optimized_compare(value, - value_is_parent=value_is_parent, - alias_secondary=alias_secondary) + return self._optimized_compare( + value, + value_is_parent=value_is_parent, + alias_secondary=alias_secondary) else: return op(self.comparator, value) @@ -1305,10 +1336,11 @@ class RelationshipProperty(StrategizedProperty): alias_secondary=True): if value is not None: value = attributes.instance_state(value) - return self._lazy_strategy.lazy_clause(value, - reverse_direction=not value_is_parent, - alias_secondary=alias_secondary, - adapt_source=adapt_source) + return self._lazy_strategy.lazy_clause( + value, + reverse_direction=not value_is_parent, + alias_secondary=alias_secondary, + adapt_source=adapt_source) def __str__(self): return str(self.parent.class_.__name__) + "." + self.key @@ -1326,7 +1358,7 @@ class RelationshipProperty(StrategizedProperty): if (source_state, r) in _recursive: return - if not "merge" in self._cascade: + if "merge" not in self._cascade: return if self.key not in source_dict: @@ -1363,8 +1395,8 @@ class RelationshipProperty(StrategizedProperty): for c in dest_list: coll.append_without_event(c) else: - dest_state.get_impl(self.key)._set_iterable(dest_state, - dest_dict, dest_list) + dest_state.get_impl(self.key)._set_iterable( + dest_state, dest_dict, dest_list) else: current = source_dict[self.key] if current is not None: @@ -1404,7 +1436,7 @@ class RelationshipProperty(StrategizedProperty): def cascade_iterator(self, type_, state, dict_, visited_states, halt_on=None): - #assert type_ in self._cascade + # assert type_ in self._cascade # only actively lazy load on the 'delete' cascade if type_ != 'delete' or self.passive_deletes: @@ -1463,16 +1495,19 @@ class RelationshipProperty(StrategizedProperty): other._reverse_property.add(self) if not other.mapper.common_parent(self.parent): - raise sa_exc.ArgumentError('reverse_property %r on ' - 'relationship %s references relationship %s, which ' - 'does not reference mapper %s' % (key, self, other, - self.parent)) + raise sa_exc.ArgumentError( + 'reverse_property %r on ' + 'relationship %s references relationship %s, which ' + 'does not reference mapper %s' % + (key, self, other, self.parent)) + if self.direction in (ONETOMANY, MANYTOONE) and self.direction \ == other.direction: - raise sa_exc.ArgumentError('%s and back-reference %s are ' - 'both of the same direction %r. Did you mean to ' - 'set remote_side on the many-to-one side ?' - % (other, self, self.direction)) + raise sa_exc.ArgumentError( + '%s and back-reference %s are ' + 'both of the same direction %r. Did you mean to ' + 'set remote_side on the many-to-one side ?' % + (other, self, self.direction)) @util.memoized_property def mapper(self): @@ -1494,9 +1529,10 @@ class RelationshipProperty(StrategizedProperty): elif isinstance(self.argument, mapperlib.Mapper): mapper_ = argument else: - raise sa_exc.ArgumentError("relationship '%s' expects " - "a class or a mapper argument (received: %s)" - % (self.key, type(argument))) + raise sa_exc.ArgumentError( + "relationship '%s' expects " + "a class or a mapper argument (received: %s)" + % (self.key, type(argument))) return mapper_ @util.memoized_property @@ -1601,17 +1637,17 @@ class RelationshipProperty(StrategizedProperty): """Test that this relationship is legal, warn about inheritance conflicts.""" - if not self.is_primary() \ - and not mapperlib.class_mapper( + if not self.is_primary() and not mapperlib.class_mapper( self.parent.class_, configure=False).has_property(self.key): - raise sa_exc.ArgumentError("Attempting to assign a new " - "relationship '%s' to a non-primary mapper on " - "class '%s'. New relationships can only be added " - "to the primary mapper, i.e. the very first mapper " - "created for class '%s' " % (self.key, - self.parent.class_.__name__, - self.parent.class_.__name__)) + raise sa_exc.ArgumentError( + "Attempting to assign a new " + "relationship '%s' to a non-primary mapper on " + "class '%s'. New relationships can only be added " + "to the primary mapper, i.e. the very first mapper " + "created for class '%s' " % + (self.key, self.parent.class_.__name__, + self.parent.class_.__name__)) # check for conflicting relationship() on superclass if not self.parent.concrete: @@ -1700,10 +1736,11 @@ class RelationshipProperty(StrategizedProperty): union(mapper.self_and_descendants) for m in check: if m.has_property(backref_key): - raise sa_exc.ArgumentError("Error creating backref " - "'%s' on relationship '%s': property of that " - "name exists on mapper '%s'" % (backref_key, - self, m)) + raise sa_exc.ArgumentError( + "Error creating backref " + "'%s' on relationship '%s': property of that " + "name exists on mapper '%s'" % + (backref_key, self, m)) # determine primaryjoin/secondaryjoin for the # backref. Use the one we had, so that @@ -1713,13 +1750,16 @@ class RelationshipProperty(StrategizedProperty): # for many to many, just switch primaryjoin/ # secondaryjoin. use the annotated # pj/sj on the _join_condition. - pj = kwargs.pop('primaryjoin', - self._join_condition.secondaryjoin_minus_local) - sj = kwargs.pop('secondaryjoin', - self._join_condition.primaryjoin_minus_local) + pj = kwargs.pop( + 'primaryjoin', + self._join_condition.secondaryjoin_minus_local) + sj = kwargs.pop( + 'secondaryjoin', + self._join_condition.primaryjoin_minus_local) else: - pj = kwargs.pop('primaryjoin', - self._join_condition.primaryjoin_reverse_remote) + pj = kwargs.pop( + 'primaryjoin', + self._join_condition.primaryjoin_reverse_remote) sj = kwargs.pop('secondaryjoin', None) if sj: raise sa_exc.InvalidRequestError( @@ -1936,24 +1976,24 @@ class JoinCondition(object): ) except sa_exc.NoForeignKeysError: if self.secondary is not None: - raise sa_exc.NoForeignKeysError("Could not determine join " - "condition between parent/child tables on " - "relationship %s - there are no foreign keys " - "linking these tables via secondary table '%s'. " - "Ensure that referencing columns are associated " - "with a ForeignKey or ForeignKeyConstraint, or " - "specify 'primaryjoin' and 'secondaryjoin' " - "expressions." - % (self.prop, self.secondary)) + raise sa_exc.NoForeignKeysError( + "Could not determine join " + "condition between parent/child tables on " + "relationship %s - there are no foreign keys " + "linking these tables via secondary table '%s'. " + "Ensure that referencing columns are associated " + "with a ForeignKey or ForeignKeyConstraint, or " + "specify 'primaryjoin' and 'secondaryjoin' " + "expressions." % (self.prop, self.secondary)) else: - raise sa_exc.NoForeignKeysError("Could not determine join " - "condition between parent/child tables on " - "relationship %s - there are no foreign keys " - "linking these tables. " - "Ensure that referencing columns are associated " - "with a ForeignKey or ForeignKeyConstraint, or " - "specify a 'primaryjoin' expression." - % self.prop) + raise sa_exc.NoForeignKeysError( + "Could not determine join " + "condition between parent/child tables on " + "relationship %s - there are no foreign keys " + "linking these tables. " + "Ensure that referencing columns are associated " + "with a ForeignKey or ForeignKeyConstraint, or " + "specify a 'primaryjoin' expression." % self.prop) except sa_exc.AmbiguousForeignKeysError: if self.secondary is not None: raise sa_exc.AmbiguousForeignKeysError( @@ -1984,7 +2024,8 @@ class JoinCondition(object): @property def secondaryjoin_minus_local(self): - return _deep_deannotate(self.secondaryjoin, values=("local", "remote")) + return _deep_deannotate(self.secondaryjoin, + values=("local", "remote")) @util.memoized_property def primaryjoin_reverse_remote(self): @@ -2262,11 +2303,10 @@ class JoinCondition(object): """ def repl(element): if self.child_selectable.c.contains_column(element) and \ - ( - not self.parent_local_selectable.c. - contains_column(element) - or self.child_local_selectable.c. - contains_column(element)): + (not self.parent_local_selectable.c. + contains_column(element) or + self.child_local_selectable.c. + contains_column(element)): return element._annotate({"remote": True}) self.primaryjoin = visitors.replacement_traverse( self.primaryjoin, {}, repl) @@ -2309,15 +2349,15 @@ class JoinCondition(object): def _check_remote_side(self): if not self.local_remote_pairs: - raise sa_exc.ArgumentError('Relationship %s could ' - 'not determine any unambiguous local/remote column ' - 'pairs based on join condition and remote_side ' - 'arguments. ' - 'Consider using the remote() annotation to ' - 'accurately mark those elements of the join ' - 'condition that are on the remote side of ' - 'the relationship.' - % (self.prop, )) + raise sa_exc.ArgumentError( + 'Relationship %s could ' + 'not determine any unambiguous local/remote column ' + 'pairs based on join condition and remote_side ' + 'arguments. ' + 'Consider using the remote() annotation to ' + 'accurately mark those elements of the join ' + 'condition that are on the remote side of ' + 'the relationship.' % (self.prop, )) def _check_foreign_cols(self, join_condition, primary): """Check the foreign key columns collected and emit error @@ -2446,10 +2486,11 @@ class JoinCondition(object): elif manytoone_fk: self.direction = MANYTOONE else: - raise sa_exc.ArgumentError("Can't determine relationship " - "direction for relationship '%s' - foreign " - "key columns are present in neither the parent " - "nor the child's mapped tables" % self.prop) + raise sa_exc.ArgumentError( + "Can't determine relationship " + "direction for relationship '%s' - foreign " + "key columns are present in neither the parent " + "nor the child's mapped tables" % self.prop) def _deannotate_pairs(self, collection): """provide deannotation for the various lists of @@ -2586,15 +2627,16 @@ class JoinCondition(object): if source_selectable is not None: primary_aliasizer = \ ClauseAdapter(secondary).\ - chain(ClauseAdapter(source_selectable, - equivalents=self.parent_equivalents)) + chain(ClauseAdapter( + source_selectable, + equivalents=self.parent_equivalents)) secondaryjoin = \ secondary_aliasizer.traverse(secondaryjoin) else: - primary_aliasizer = ClauseAdapter(dest_selectable, - exclude_fn=_ColInAnnotations( - "local"), - equivalents=self.child_equivalents) + primary_aliasizer = ClauseAdapter( + dest_selectable, + exclude_fn=_ColInAnnotations("local"), + equivalents=self.child_equivalents) if source_selectable is not None: primary_aliasizer.chain( ClauseAdapter(source_selectable, diff --git a/lib/sqlalchemy/orm/session.py b/lib/sqlalchemy/orm/session.py index 77cd6628b..036045dba 100644 --- a/lib/sqlalchemy/orm/session.py +++ b/lib/sqlalchemy/orm/session.py @@ -24,7 +24,8 @@ from .unitofwork import UOWTransaction from . import state as statelib import sys -__all__ = ['Session', 'SessionTransaction', 'SessionExtension', 'sessionmaker'] +__all__ = ['Session', 'SessionTransaction', + 'SessionExtension', 'sessionmaker'] _sessions = weakref.WeakValueDictionary() """Weak-referencing dictionary of :class:`.Session` objects. @@ -274,7 +275,7 @@ class SessionTransaction(object): for s in set(self._deleted).union(self.session._deleted): if s.deleted: - #assert s in self._deleted + # assert s in self._deleted del s.deleted self.session._update_impl(s, discard_existing=True) @@ -501,16 +502,16 @@ class Session(_SessionClassMethods): .. warning:: - The autocommit flag is **not for general use**, and if it is used, - queries should only be invoked within the span of a - :meth:`.Session.begin` / :meth:`.Session.commit` pair. Executing + The autocommit flag is **not for general use**, and if it is + used, queries should only be invoked within the span of a + :meth:`.Session.begin` / :meth:`.Session.commit` pair. Executing queries outside of a demarcated transaction is a legacy mode of usage, and can in some cases lead to concurrent connection checkouts. Defaults to ``False``. When ``True``, the - :class:`.Session` does not keep a persistent transaction running, and - will acquire connections from the engine on an as-needed basis, + :class:`.Session` does not keep a persistent transaction running, + and will acquire connections from the engine on an as-needed basis, returning them immediately after their use. Flushes will begin and commit (or possibly rollback) their own transaction if no transaction is present. When using this mode, the @@ -525,8 +526,8 @@ class Session(_SessionClassMethods): :meth:`~.Session.flush` call to this ``Session`` before proceeding. This is a convenience feature so that :meth:`~.Session.flush` need not be called repeatedly in order for database queries to retrieve - results. It's typical that ``autoflush`` is used in conjunction with - ``autocommit=False``. In this scenario, explicit calls to + results. It's typical that ``autoflush`` is used in conjunction + with ``autocommit=False``. In this scenario, explicit calls to :meth:`~.Session.flush` are rarely needed; you usually only need to call :meth:`~.Session.commit` (which flushes) to finalize changes. @@ -542,8 +543,8 @@ class Session(_SessionClassMethods): :class:`.Engine` or :class:`.Connection` objects. Operations which proceed relative to a particular :class:`.Mapper` will consult this dictionary for the direct :class:`.Mapper` instance as - well as the mapper's ``mapped_table`` attribute in order to locate a - connectable to use. The full resolution is described in the + well as the mapper's ``mapped_table`` attribute in order to locate + a connectable to use. The full resolution is described in the :meth:`.Session.get_bind`. Usage looks like:: @@ -566,8 +567,8 @@ class Session(_SessionClassMethods): legacy-only flag which when ``False`` disables *all* 0.5-style object accounting on transaction boundaries, including auto-expiry of instances on rollback and commit, maintenance of the "new" and - "deleted" lists upon rollback, and autoflush of pending changes upon - :meth:`~.Session.begin`, all of which are interdependent. + "deleted" lists upon rollback, and autoflush of pending changes + upon :meth:`~.Session.begin`, all of which are interdependent. :param expire_on_commit: Defaults to ``True``. When ``True``, all instances will be fully expired after each :meth:`~.commit`, @@ -581,25 +582,26 @@ class Session(_SessionClassMethods): Please see :class:`.SessionEvents`. :param info: optional dictionary of arbitrary data to be associated - with this :class:`.Session`. Is available via the :attr:`.Session.info` - attribute. Note the dictionary is copied at construction time so - that modifications to the per-:class:`.Session` dictionary will be local - to that :class:`.Session`. + with this :class:`.Session`. Is available via the + :attr:`.Session.info` attribute. Note the dictionary is copied at + construction time so that modifications to the per- + :class:`.Session` dictionary will be local to that + :class:`.Session`. .. versionadded:: 0.9.0 :param query_cls: Class which should be used to create new Query - objects, as returned by the :meth:`~.Session.query` method. Defaults - to :class:`.Query`. + objects, as returned by the :meth:`~.Session.query` method. + Defaults to :class:`.Query`. :param twophase: When ``True``, all transactions will be started as a "two phase" transaction, i.e. using the "two phase" semantics of the database in use along with an XID. During a :meth:`~.commit`, after :meth:`~.flush` has been issued for all - attached databases, the :meth:`~.TwoPhaseTransaction.prepare` method - on each database's :class:`.TwoPhaseTransaction` will be called. - This allows each database to roll back the entire transaction, - before each transaction is committed. + attached databases, the :meth:`~.TwoPhaseTransaction.prepare` + method on each database's :class:`.TwoPhaseTransaction` will be + called. This allows each database to roll back the entire + transaction, before each transaction is committed. :param weak_identity_map: Defaults to ``True`` - when set to ``False``, objects placed in the :class:`.Session` will be @@ -829,12 +831,12 @@ class Session(_SessionClassMethods): etc.) which will be used to locate a bind, if a bind cannot otherwise be identified. - :param close_with_result: Passed to :meth:`.Engine.connect`, indicating - the :class:`.Connection` should be considered "single use", - automatically closing when the first result set is closed. This - flag only has an effect if this :class:`.Session` is configured with - ``autocommit=True`` and does not already have a transaction - in progress. + :param close_with_result: Passed to :meth:`.Engine.connect`, + indicating the :class:`.Connection` should be considered + "single use", automatically closing when the first result set is + closed. This flag only has an effect if this :class:`.Session` is + configured with ``autocommit=True`` and does not already have a + transaction in progress. :param \**kw: Additional keyword arguments are sent to :meth:`get_bind()`, @@ -869,8 +871,8 @@ class Session(_SessionClassMethods): user_table.select().where(user_table.c.id == 5) ) - :meth:`~.Session.execute` accepts any executable clause construct, such - as :func:`~.sql.expression.select`, + :meth:`~.Session.execute` accepts any executable clause construct, + such as :func:`~.sql.expression.select`, :func:`~.sql.expression.insert`, :func:`~.sql.expression.update`, :func:`~.sql.expression.delete`, and @@ -899,7 +901,8 @@ class Session(_SessionClassMethods): cursor's ``execute()`` or ``executemany()`` is used to execute the statement. An INSERT construct may be invoked for a single row:: - result = session.execute(users.insert(), {"id": 7, "name": "somename"}) + result = session.execute( + users.insert(), {"id": 7, "name": "somename"}) or for multiple rows:: @@ -917,8 +920,9 @@ class Session(_SessionClassMethods): :class:`.Connection`, which in the average case is derived directly from the "bind" of the :class:`.Session` itself, and in other cases can be based on the :func:`.mapper` - and :class:`.Table` objects passed to the method; see the documentation - for :meth:`.Session.get_bind` for a full description of this scheme. + and :class:`.Table` objects passed to the method; see the + documentation for :meth:`.Session.get_bind` for a full description of + this scheme. The :meth:`.Session.execute` method does *not* invoke autoflush. @@ -980,8 +984,8 @@ class Session(_SessionClassMethods): if bind is None: bind = self.get_bind(mapper, clause=clause, **kw) - return self._connection_for_bind(bind, close_with_result=True).execute( - clause, params or {}) + return self._connection_for_bind( + bind, close_with_result=True).execute(clause, params or {}) def scalar(self, clause, params=None, mapper=None, bind=None, **kw): """Like :meth:`~.Session.execute` but return a scalar result.""" @@ -1551,10 +1555,10 @@ class Session(_SessionClassMethods): same primary key in the session. If not found locally, it attempts to load the object from the database based on primary key, and if none can be located, creates a new instance. The state of each - attribute on the source instance is then copied to the target instance. - The resulting target instance is then returned by the method; the - original source instance is left unmodified, and un-associated with the - :class:`.Session` if not already. + attribute on the source instance is then copied to the target + instance. The resulting target instance is then returned by the + method; the original source instance is left unmodified, and + un-associated with the :class:`.Session` if not already. This operation cascades to associated instances if the association is mapped with ``cascade="merge"``. @@ -1582,7 +1586,8 @@ class Session(_SessionClassMethods): any existing related objects or collections that might not be loaded. The resulting objects from ``load=False`` are always produced as "clean", so it is only appropriate that the given objects - should be "clean" as well, else this suggests a mis-use of the method. + should be "clean" as well, else this suggests a mis-use of the + method. """ @@ -1713,8 +1718,8 @@ class Session(_SessionClassMethods): def _save_impl(self, state): if state.key is not None: raise sa_exc.InvalidRequestError( - "Object '%s' already has an identity - it can't be registered " - "as pending" % state_str(state)) + "Object '%s' already has an identity - " + "it can't be registered as pending" % state_str(state)) self._before_attach(state) if state not in self._new: @@ -1790,8 +1795,8 @@ class Session(_SessionClassMethods): is what was already loaded from a foreign-key-holding value. The :meth:`.Session.enable_relationship_loading` method is - similar to the ``load_on_pending`` flag on :func:`.relationship`. Unlike - that flag, :meth:`.Session.enable_relationship_loading` allows + similar to the ``load_on_pending`` flag on :func:`.relationship`. + Unlike that flag, :meth:`.Session.enable_relationship_loading` allows an object to remain transient while still being able to load related items. @@ -1827,10 +1832,10 @@ class Session(_SessionClassMethods): if state.key and \ state.key in self.identity_map and \ not self.identity_map.contains_state(state): - raise sa_exc.InvalidRequestError("Can't attach instance " - "%s; another instance with key %s is already " - "present in this session." - % (state_str(state), state.key)) + raise sa_exc.InvalidRequestError( + "Can't attach instance " + "%s; another instance with key %s is already " + "present in this session." % (state_str(state), state.key)) if state.session_id and \ state.session_id is not self.hash_key and \ @@ -2007,8 +2012,8 @@ class Session(_SessionClassMethods): instance_dict=self.identity_map) util.warn("Attribute history events accumulated on %d " "previously clean instances " - "within inner-flush event handlers have been reset, " - "and will not result in database updates. " + "within inner-flush event handlers have been " + "reset, and will not result in database updates. " "Consider using set_committed_value() within " "inner-flush event handlers to avoid this warning." % len_) @@ -2057,12 +2062,12 @@ class Session(_SessionClassMethods): A few caveats to this method apply: - * Instances present in the :attr:`.Session.dirty` collection may report - ``False`` when tested with this method. This is because - the object may have received change events via attribute - mutation, thus placing it in :attr:`.Session.dirty`, - but ultimately the state is the same as that loaded from - the database, resulting in no net change here. + * Instances present in the :attr:`.Session.dirty` collection may + report ``False`` when tested with this method. This is because + the object may have received change events via attribute mutation, + thus placing it in :attr:`.Session.dirty`, but ultimately the state + is the same as that loaded from the database, resulting in no net + change here. * Scalar attributes may not have recorded the previously set value when a new value was applied, if the attribute was not loaded, or was expired, at the time the new value was received - in these @@ -2148,8 +2153,8 @@ class Session(_SessionClassMethods): call :meth:`.Session.rollback`, in order to close out the transaction stack. It is in this "partial rollback" period that the :attr:`.is_active` flag returns False. After the call to - :meth:`.Session.rollback`, the :class:`.SessionTransaction` is replaced - with a new one and :attr:`.is_active` returns ``True`` again. + :meth:`.Session.rollback`, the :class:`.SessionTransaction` is + replaced with a new one and :attr:`.is_active` returns ``True`` again. When a :class:`.Session` is used in ``autocommit=True`` mode, the :class:`.SessionTransaction` is only instantiated within the scope @@ -2315,8 +2320,8 @@ class sessionmaker(_SessionClassMethods): .. versionadded:: 0.9.0 - :param \**kw: all other keyword arguments are passed to the constructor - of newly created :class:`.Session` objects. + :param \**kw: all other keyword arguments are passed to the + constructor of newly created :class:`.Session` objects. """ kw['bind'] = bind diff --git a/lib/sqlalchemy/orm/state.py b/lib/sqlalchemy/orm/state.py index 942857362..a9024b468 100644 --- a/lib/sqlalchemy/orm/state.py +++ b/lib/sqlalchemy/orm/state.py @@ -277,8 +277,8 @@ class InstanceState(interfaces._InspectionAttr): state_dict = {'instance': self.obj()} state_dict.update( (k, self.__dict__[k]) for k in ( - 'committed_state', '_pending_mutations', 'modified', 'expired', - 'callables', 'key', 'parents', 'load_options', + 'committed_state', '_pending_mutations', 'modified', + 'expired', 'callables', 'key', 'parents', 'load_options', 'class_', ) if k in self.__dict__ ) diff --git a/lib/sqlalchemy/orm/strategies.py b/lib/sqlalchemy/orm/strategies.py index eba7379a3..e54cf8c4b 100644 --- a/lib/sqlalchemy/orm/strategies.py +++ b/lib/sqlalchemy/orm/strategies.py @@ -49,8 +49,8 @@ def _register_attribute(strategy, mapper, useobject, if prop.key in prop.parent.validators: fn, opts = prop.parent.validators[prop.key] listen_hooks.append( - lambda desc, prop: orm_util._validator_events(desc, - prop.key, fn, **opts) + lambda desc, prop: orm_util._validator_events( + desc, prop.key, fn, **opts) ) if useobject: @@ -77,8 +77,9 @@ def _register_attribute(strategy, mapper, useobject, compare_function=compare_function, useobject=useobject, extension=attribute_ext, - trackparent=useobject and (prop.single_parent - or prop.direction is interfaces.ONETOMANY), + trackparent=useobject and ( + prop.single_parent or + prop.direction is interfaces.ONETOMANY), typecallable=typecallable, callable_=callable_, active_history=active_history, @@ -268,8 +269,9 @@ class DeferredColumnLoader(LoaderStrategy): ) query = session.query(localparent) - if loading.load_on_ident(query, state.key, - only_load_props=group, refresh_state=state) is None: + if loading.load_on_ident( + query, state.key, only_load_props=group, + refresh_state=state) is None: raise orm_exc.ObjectDeletedError(state) return attributes.ATTR_WAS_SET @@ -312,11 +314,12 @@ class NoLoader(AbstractRelationshipLoader): def init_class_attribute(self, mapper): self.is_class_level = True - _register_attribute(self, mapper, - useobject=True, - uselist=self.parent_property.uselist, - typecallable=self.parent_property.collection_class, - ) + _register_attribute( + self, mapper, + useobject=True, + uselist=self.parent_property.uselist, + typecallable=self.parent_property.collection_class, + ) def create_row_processor( self, context, path, loadopt, mapper, row, adapter): @@ -381,15 +384,15 @@ class LazyLoader(AbstractRelationshipLoader): # will enable active_history # in that case. otherwise we don't need the # "old" value during backref operations. - _register_attribute(self, - mapper, - useobject=True, - callable_=self._load_for_state, - uselist=self.parent_property.uselist, - backref=self.parent_property.back_populates, - typecallable=self.parent_property.collection_class, - active_history=active_history - ) + _register_attribute( + self, mapper, + useobject=True, + callable_=self._load_for_state, + uselist=self.parent_property.uselist, + backref=self.parent_property.back_populates, + typecallable=self.parent_property.collection_class, + active_history=active_history + ) def lazy_clause(self, state, reverse_direction=False, alias_secondary=False, @@ -1135,16 +1138,16 @@ class JoinedLoader(AbstractRelationshipLoader): root_mapper, prop = path[-2:] - #from .mapper import Mapper - #from .interfaces import MapperProperty - #assert isinstance(root_mapper, Mapper) - #assert isinstance(prop, MapperProperty) + # from .mapper import Mapper + # from .interfaces import MapperProperty + # assert isinstance(root_mapper, Mapper) + # assert isinstance(prop, MapperProperty) if alias is not None: if isinstance(alias, str): alias = prop.target.alias(alias) - adapter = sql_util.ColumnAdapter(alias, - equivalents=prop.mapper._equivalent_columns) + adapter = sql_util.ColumnAdapter( + alias, equivalents=prop.mapper._equivalent_columns) else: if path.contains(context.attributes, "path_with_polymorphic"): with_poly_info = path.get(context.attributes, @@ -1161,8 +1164,8 @@ class JoinedLoader(AbstractRelationshipLoader): return adapter - def _setup_query_on_user_defined_adapter(self, context, entity, - path, adapter, user_defined_adapter): + def _setup_query_on_user_defined_adapter( + self, context, entity, path, adapter, user_defined_adapter): # apply some more wrapping to the "user defined adapter" # if we are setting up the query for SQL render. diff --git a/lib/sqlalchemy/orm/strategy_options.py b/lib/sqlalchemy/orm/strategy_options.py index 7518da819..392f7cec2 100644 --- a/lib/sqlalchemy/orm/strategy_options.py +++ b/lib/sqlalchemy/orm/strategy_options.py @@ -21,13 +21,15 @@ from .path_registry import PathRegistry, TokenRegistry, \ class Load(Generative, MapperOption): """Represents loader options which modify the state of a - :class:`.Query` in order to affect how various mapped attributes are loaded. + :class:`.Query` in order to affect how various mapped attributes are + loaded. .. versionadded:: 0.9.0 The :meth:`.Load` system is a new foundation for the existing system of loader options, including options such as - :func:`.orm.joinedload`, :func:`.orm.defer`, and others. In particular, - it introduces a new method-chained system that replaces the need for - dot-separated paths as well as "_all()" options such as :func:`.orm.joinedload_all`. + :func:`.orm.joinedload`, :func:`.orm.defer`, and others. In + particular, it introduces a new method-chained system that replaces the + need for dot-separated paths as well as "_all()" options such as + :func:`.orm.joinedload_all`. A :class:`.Load` object can be used directly or indirectly. To use one directly, instantiate given the parent class. This style of usage is @@ -42,11 +44,12 @@ class Load(Generative, MapperOption): session.query(MyClass).options(myopt) The :class:`.Load` construct is invoked indirectly whenever one makes use - of the various loader options that are present in ``sqlalchemy.orm``, including - options such as :func:`.orm.joinedload`, :func:`.orm.defer`, :func:`.orm.subqueryload`, - and all the rest. These constructs produce an "anonymous" form of the - :class:`.Load` object which tracks attributes and options, but is not linked - to a parent class until it is associated with a parent :class:`.Query`:: + of the various loader options that are present in ``sqlalchemy.orm``, + including options such as :func:`.orm.joinedload`, :func:`.orm.defer`, + :func:`.orm.subqueryload`, and all the rest. These constructs produce an + "anonymous" form of the :class:`.Load` object which tracks attributes and + options, but is not linked to a parent class until it is associated with a + parent :class:`.Query`:: # produce "unbound" Load object myopt = joinedload("widgets") @@ -56,11 +59,12 @@ class Load(Generative, MapperOption): session.query(MyClass).options(myopt) Whether the direct or indirect style is used, the :class:`.Load` object - returned now represents a specific "path" along the entities of a :class:`.Query`. - This path can be traversed using a standard method-chaining approach. - Supposing a class hierarchy such as ``User``, ``User.addresses -> Address``, - ``User.orders -> Order`` and ``Order.items -> Item``, we can specify a variety - of loader options along each element in the "path":: + returned now represents a specific "path" along the entities of a + :class:`.Query`. This path can be traversed using a standard + method-chaining approach. Supposing a class hierarchy such as ``User``, + ``User.addresses -> Address``, ``User.orders -> Order`` and + ``Order.items -> Item``, we can specify a variety of loader options along + each element in the "path":: session.query(User).options( joinedload("addresses"), @@ -68,8 +72,8 @@ class Load(Generative, MapperOption): ) Where above, the ``addresses`` collection will be joined-loaded, the - ``orders`` collection will be subquery-loaded, and within that subquery load - the ``items`` collection will be joined-loaded. + ``orders`` collection will be subquery-loaded, and within that subquery + load the ``items`` collection will be joined-loaded. """ @@ -147,8 +151,9 @@ class Load(Generative, MapperOption): if not prop.parent.common_parent(path.mapper): if raiseerr: - raise sa_exc.ArgumentError("Attribute '%s' does not " - "link from element '%s'" % (attr, path.entity)) + raise sa_exc.ArgumentError( + "Attribute '%s' does not " + "link from element '%s'" % (attr, path.entity)) else: return None @@ -162,8 +167,8 @@ class Load(Generative, MapperOption): ext_info.mapper.base_mapper, ext_info.mapper, aliased=True, _use_mapper_path=True) - path.entity_path[prop].set(self.context, - "path_with_polymorphic", inspect(ac)) + path.entity_path[prop].set( + self.context, "path_with_polymorphic", inspect(ac)) path = path[prop][path_element] else: path = path[prop] @@ -228,7 +233,8 @@ class Load(Generative, MapperOption): if i == 0 and c_token.endswith(':' + _DEFAULT_TOKEN): return to_chop - elif c_token != 'relationship:%s' % (_WILDCARD_TOKEN,) and c_token != p_token.key: + elif c_token != 'relationship:%s' % (_WILDCARD_TOKEN,) and \ + c_token != p_token.key: return None if c_token is p_token: @@ -324,11 +330,13 @@ class _UnboundLoad(Load): def _chop_path(self, to_chop, path): i = -1 - for i, (c_token, (p_mapper, p_prop)) in enumerate(zip(to_chop, path.pairs())): + for i, (c_token, (p_mapper, p_prop)) in enumerate( + zip(to_chop, path.pairs())): if isinstance(c_token, util.string_types): if i == 0 and c_token.endswith(':' + _DEFAULT_TOKEN): return to_chop - elif c_token != 'relationship:%s' % (_WILDCARD_TOKEN,) and c_token != p_prop.key: + elif c_token != 'relationship:%s' % ( + _WILDCARD_TOKEN,) and c_token != p_prop.key: return None elif isinstance(c_token, PropComparator): if c_token.property is not p_prop: @@ -392,8 +400,8 @@ class _UnboundLoad(Load): effective_path = loader.path # prioritize "first class" options over those - # that were "links in the chain", e.g. "x" and "y" in someload("x.y.z") - # versus someload("x") / someload("x.y") + # that were "links in the chain", e.g. "x" and "y" in + # someload("x.y.z") versus someload("x") / someload("x.y") if self._is_chain_link: effective_path.setdefault(context, "loader", loader) else: @@ -564,8 +572,8 @@ def load_only(loadopt, *attrs): session.query(User).options(load_only("name", "fullname")) Example - given a relationship ``User.addresses -> Address``, specify - subquery loading for the ``User.addresses`` collection, but on each ``Address`` - object load only the ``email_address`` attribute:: + subquery loading for the ``User.addresses`` collection, but on each + ``Address`` object load only the ``email_address`` attribute:: session.query(User).options( subqueryload("addreses").load_only("email_address") @@ -625,22 +633,25 @@ def joinedload(loadopt, attr, innerjoin=None): If the joined-eager load is chained onto an existing LEFT OUTER JOIN, ``innerjoin=True`` will be bypassed and the join will continue to - chain as LEFT OUTER JOIN so that the results don't change. As an alternative, - specify the value ``"nested"``. This will instead nest the join - on the right side, e.g. using the form "a LEFT OUTER JOIN (b JOIN c)". + chain as LEFT OUTER JOIN so that the results don't change. As an + alternative, specify the value ``"nested"``. This will instead nest the + join on the right side, e.g. using the form "a LEFT OUTER JOIN + (b JOIN c)". .. versionadded:: 0.9.4 Added ``innerjoin="nested"`` option to support nesting of eager "inner" joins. .. note:: - The joins produced by :func:`.orm.joinedload` are **anonymously aliased**. - The criteria by which the join proceeds cannot be modified, nor can the - :class:`.Query` refer to these joins in any way, including ordering. + The joins produced by :func:`.orm.joinedload` are **anonymously + aliased**. The criteria by which the join proceeds cannot be + modified, nor can the :class:`.Query` refer to these joins in any way, + including ordering. To produce a specific SQL JOIN which is explicitly available, use :meth:`.Query.join`. To combine explicit JOINs with eager loading - of collections, use :func:`.orm.contains_eager`; see :ref:`contains_eager`. + of collections, use :func:`.orm.contains_eager`; see + :ref:`contains_eager`. .. seealso:: @@ -654,8 +665,8 @@ def joinedload(loadopt, attr, innerjoin=None): :paramref:`.relationship.lazy` - :paramref:`.relationship.innerjoin` - :func:`.relationship`-level version - of the :paramref:`.joinedload.innerjoin` option. + :paramref:`.relationship.innerjoin` - :func:`.relationship`-level + version of the :paramref:`.joinedload.innerjoin` option. """ loader = loadopt.set_relationship_strategy(attr, {"lazy": "joined"}) @@ -772,7 +783,8 @@ def immediateload(loadopt, attr): @immediateload._add_unbound_fn def immediateload(*keys): - return _UnboundLoad._from_keys(_UnboundLoad.immediateload, keys, False, {}) + return _UnboundLoad._from_keys( + _UnboundLoad.immediateload, keys, False, {}) @loader_option() @@ -891,8 +903,8 @@ def defer(key, *addl_attrs): @loader_option() def undefer(loadopt, key): - """Indicate that the given column-oriented attribute should be undeferred, e.g. - specified within the SELECT statement of the entity as a whole. + """Indicate that the given column-oriented attribute should be undeferred, + e.g. specified within the SELECT statement of the entity as a whole. The column being undeferred is typically set up on the mapping as a :func:`.deferred` attribute. @@ -906,7 +918,8 @@ def undefer(loadopt, key): session.query(MyClass).options(undefer("col1"), undefer("col2")) # undefer all columns specific to a single class using Load + * - session.query(MyClass, MyOtherClass).options(Load(MyClass).undefer("*")) + session.query(MyClass, MyOtherClass).options( + Load(MyClass).undefer("*")) :param key: Attribute to be undeferred. @@ -937,7 +950,8 @@ def undefer(key, *addl_attrs): @loader_option() def undefer_group(loadopt, name): - """Indicate that columns within the given deferred group name should be undeferred. + """Indicate that columns within the given deferred group name should be + undeferred. The columns being undeferred are set up on the mapping as :func:`.deferred` attributes and include a "group" name. @@ -947,9 +961,11 @@ def undefer_group(loadopt, name): session.query(MyClass).options(undefer_group("large_attrs")) To undefer a group of attributes on a related entity, the path can be - spelled out using relationship loader options, such as :func:`.orm.defaultload`:: + spelled out using relationship loader options, such as + :func:`.orm.defaultload`:: - session.query(MyClass).options(defaultload("someattr").undefer_group("large_attrs")) + session.query(MyClass).options( + defaultload("someattr").undefer_group("large_attrs")) .. versionchanged:: 0.9.0 :func:`.orm.undefer_group` is now specific to a particiular entity load path. diff --git a/lib/sqlalchemy/orm/sync.py b/lib/sqlalchemy/orm/sync.py index 55b06cd5c..e1ef85c1d 100644 --- a/lib/sqlalchemy/orm/sync.py +++ b/lib/sqlalchemy/orm/sync.py @@ -96,8 +96,8 @@ def source_modified(uowcommit, source, source_mapper, synchronize_pairs): prop = source_mapper._columntoproperty[l] except exc.UnmappedColumnError: _raise_col_to_prop(False, source_mapper, l, None, r) - history = uowcommit.get_attribute_history(source, prop.key, - attributes.PASSIVE_NO_INITIALIZE) + history = uowcommit.get_attribute_history( + source, prop.key, attributes.PASSIVE_NO_INITIALIZE) if bool(history.deleted): return True else: @@ -107,16 +107,17 @@ def source_modified(uowcommit, source, source_mapper, synchronize_pairs): def _raise_col_to_prop(isdest, source_mapper, source_column, dest_mapper, dest_column): if isdest: - raise exc.UnmappedColumnError("Can't execute sync rule for " - "destination column '%s'; mapper '%s' does not map " - "this column. Try using an explicit `foreign_keys` " - "collection which does not include this column (or use " - "a viewonly=True relation)." % (dest_column, - dest_mapper)) + raise exc.UnmappedColumnError( + "Can't execute sync rule for " + "destination column '%s'; mapper '%s' does not map " + "this column. Try using an explicit `foreign_keys` " + "collection which does not include this column (or use " + "a viewonly=True relation)." % (dest_column, dest_mapper)) else: - raise exc.UnmappedColumnError("Can't execute sync rule for " - "source column '%s'; mapper '%s' does not map this " - "column. Try using an explicit `foreign_keys` " - "collection which does not include destination column " - "'%s' (or use a viewonly=True relation)." - % (source_column, source_mapper, dest_column)) + raise exc.UnmappedColumnError( + "Can't execute sync rule for " + "source column '%s'; mapper '%s' does not map this " + "column. Try using an explicit `foreign_keys` " + "collection which does not include destination column " + "'%s' (or use a viewonly=True relation)." % + (source_column, source_mapper, dest_column)) diff --git a/lib/sqlalchemy/orm/unitofwork.py b/lib/sqlalchemy/orm/unitofwork.py index d705f0cb2..71e61827b 100644 --- a/lib/sqlalchemy/orm/unitofwork.py +++ b/lib/sqlalchemy/orm/unitofwork.py @@ -350,7 +350,7 @@ class UOWTransaction(object): def execute(self): postsort_actions = self._generate_actions() - #sort = topological.sort(self.dependencies, postsort_actions) + # sort = topological.sort(self.dependencies, postsort_actions) # print "--------------" # print "\ndependencies:", self.dependencies # print "\ncycles:", self.cycles @@ -430,9 +430,9 @@ class Preprocess(IterateMappersMixin): if (delete_states or save_states): if not self.setup_flush_actions and ( - self.dependency_processor. + self.dependency_processor. prop_has_changes(uow, delete_states, True) or - self.dependency_processor. + self.dependency_processor. prop_has_changes(uow, save_states, False) ): self.dependency_processor.per_property_flush_actions(uow) diff --git a/lib/sqlalchemy/orm/util.py b/lib/sqlalchemy/orm/util.py index 0d433ac43..215de5f4b 100644 --- a/lib/sqlalchemy/orm/util.py +++ b/lib/sqlalchemy/orm/util.py @@ -71,8 +71,11 @@ class CascadeOptions(frozenset): ) -def _validator_events(desc, key, validator, include_removes, include_backrefs): - """Runs a validation method on an attribute value to be set or appended.""" +def _validator_events( + desc, key, validator, include_removes, include_backrefs): + """Runs a validation method on an attribute value to be set or + appended. + """ if not include_backrefs: def detect_is_backref(state, initiator): @@ -169,8 +172,9 @@ def polymorphic_union(table_map, typecolname, if typecolname is not None: result.append( sql.select([col(name, table) for name in colnames] + - [sql.literal_column(sql_util._quote_ddl_expr(type)). - label(typecolname)], + [sql.literal_column( + sql_util._quote_ddl_expr(type)). + label(typecolname)], from_obj=[table])) else: result.append(sql.select([col(name, table) for name in colnames], @@ -225,7 +229,8 @@ def identity_key(*args, **kwargs): E.g.:: - >>> row = engine.execute("select * from table where a=1 and b=2").first() + >>> row = engine.execute("select * from table where a=1 and b=2").\ +first() >>> identity_key(MyClass, row=row) (<class '__main__.MyClass'>, (1, 2)) @@ -246,8 +251,9 @@ def identity_key(*args, **kwargs): elif len(args) == 3: class_, ident = args else: - raise sa_exc.ArgumentError("expected up to three " - "positional arguments, got %s" % len(args)) + raise sa_exc.ArgumentError( + "expected up to three positional arguments, " + "got %s" % len(args)) if kwargs: raise sa_exc.ArgumentError("unknown keyword arguments: %s" % ", ".join(kwargs)) @@ -454,9 +460,9 @@ class AliasedInsp(_InspectionAttr): self._base_alias = _base_alias or self self._use_mapper_path = _use_mapper_path - self._adapter = sql_util.ClauseAdapter(selectable, - equivalents=mapper._equivalent_columns, - adapt_on_names=adapt_on_names) + self._adapter = sql_util.ClauseAdapter( + selectable, equivalents=mapper._equivalent_columns, + adapt_on_names=adapt_on_names) self._adapt_on_names = adapt_on_names self._target = mapper.class_ @@ -526,7 +532,8 @@ class AliasedInsp(_InspectionAttr): elif mapper.isa(self.mapper): return self else: - assert False, "mapper %s doesn't correspond to %s" % (mapper, self) + assert False, "mapper %s doesn't correspond to %s" % ( + mapper, self) def __repr__(self): return '<AliasedInsp at 0x%x; %s>' % ( @@ -577,11 +584,12 @@ def aliased(element, alias=None, name=None, flat=False, adapt_on_names=False): attribute name that will be accessible via tuples returned by a :class:`.Query` object. - :param flat: Boolean, will be passed through to the :meth:`.FromClause.alias` - call so that aliases of :class:`.Join` objects don't include an enclosing - SELECT. This can lead to more efficient queries in many circumstances. - A JOIN against a nested JOIN will be rewritten as a JOIN against an aliased - SELECT subquery on backends that don't support this syntax. + :param flat: Boolean, will be passed through to the + :meth:`.FromClause.alias` call so that aliases of :class:`.Join` objects + don't include an enclosing SELECT. This can lead to more efficient + queries in many circumstances. A JOIN against a nested JOIN will be + rewritten as a JOIN against an aliased SELECT subquery on backends that + don't support this syntax. .. versionadded:: 0.9.0 @@ -664,11 +672,12 @@ def with_polymorphic(base, classes, selectable=False, support parenthesized joins, such as SQLite and older versions of MySQL. - :param flat: Boolean, will be passed through to the :meth:`.FromClause.alias` - call so that aliases of :class:`.Join` objects don't include an enclosing - SELECT. This can lead to more efficient queries in many circumstances. - A JOIN against a nested JOIN will be rewritten as a JOIN against an aliased - SELECT subquery on backends that don't support this syntax. + :param flat: Boolean, will be passed through to the + :meth:`.FromClause.alias` call so that aliases of :class:`.Join` + objects don't include an enclosing SELECT. This can lead to more + efficient queries in many circumstances. A JOIN against a nested JOIN + will be rewritten as a JOIN against an aliased SELECT subquery on + backends that don't support this syntax. Setting ``flat`` to ``True`` implies the ``aliased`` flag is also ``True``. @@ -765,7 +774,8 @@ class _ORMJoin(expression.Join): prop = None if prop: - if sql_util.clause_is_present(on_selectable, left_info.selectable): + if sql_util.clause_is_present( + on_selectable, left_info.selectable): adapt_from = on_selectable else: adapt_from = left_info.selectable @@ -936,9 +946,9 @@ def randomize_unitofwork(): By calling ``randomize_unitofwork()`` when a script first runs, the ordering of a key series of sets within the unit of work implementation - are randomized, so that the script can be minimized down to the fundamental - mapping and operation that's failing, while still reproducing the issue - on at least some runs. + are randomized, so that the script can be minimized down to the + fundamental mapping and operation that's failing, while still reproducing + the issue on at least some runs. This utility is also available when running the test suite via the ``--reversetop`` flag. |