diff options
Diffstat (limited to 'lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/util.py')
-rwxr-xr-x | lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/util.py | 625 |
1 files changed, 0 insertions, 625 deletions
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/util.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/util.py deleted file mode 100755 index 8448b545..00000000 --- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/util.py +++ /dev/null @@ -1,625 +0,0 @@ -# orm/util.py -# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file> -# -# This module is part of SQLAlchemy and is released under -# the MIT License: http://www.opensource.org/licenses/mit-license.php - - -from sqlalchemy import sql, util, event, exc as sa_exc -from sqlalchemy.sql import expression, util as sql_util, operators -from sqlalchemy.orm.interfaces import MapperExtension, EXT_CONTINUE,\ - PropComparator, MapperProperty -from sqlalchemy.orm import attributes, exc -import operator - -mapperlib = util.importlater("sqlalchemy.orm", "mapperlib") - -all_cascades = frozenset(("delete", "delete-orphan", "all", "merge", - "expunge", "save-update", "refresh-expire", - "none")) - -_INSTRUMENTOR = ('mapper', 'instrumentor') - -class CascadeOptions(dict): - """Keeps track of the options sent to relationship().cascade""" - - def __init__(self, arg=""): - if not arg: - values = set() - else: - values = set(c.strip() for c in arg.split(',')) - - for name in ['save-update', 'delete', 'refresh-expire', - 'merge', 'expunge']: - boolean = name in values or 'all' in values - setattr(self, name.replace('-', '_'), boolean) - if boolean: - self[name] = True - self.delete_orphan = "delete-orphan" in values - if self.delete_orphan: - self['delete-orphan'] = True - - if self.delete_orphan and not self.delete: - util.warn("The 'delete-orphan' cascade option requires " - "'delete'. This will raise an error in 0.6.") - - for x in values: - if x not in all_cascades: - raise sa_exc.ArgumentError("Invalid cascade option '%s'" % x) - - def __repr__(self): - return "CascadeOptions(%s)" % repr(",".join( - [x for x in ['delete', 'save_update', 'merge', 'expunge', - 'delete_orphan', 'refresh-expire'] - if getattr(self, x, False) is True])) - -def _validator_events(desc, key, validator): - """Runs a validation method on an attribute value to be set or appended.""" - - def append(state, value, initiator): - return validator(state.obj(), key, value) - - def set_(state, value, oldvalue, initiator): - return validator(state.obj(), key, value) - - event.listen(desc, 'append', append, raw=True, retval=True) - event.listen(desc, 'set', set_, raw=True, retval=True) - -def polymorphic_union(table_map, typecolname, aliasname='p_union', cast_nulls=True): - """Create a ``UNION`` statement used by a polymorphic mapper. - - See :ref:`concrete_inheritance` for an example of how - this is used. - - :param table_map: mapping of polymorphic identities to - :class:`.Table` objects. - :param typecolname: string name of a "discriminator" column, which will be - derived from the query, producing the polymorphic identity for each row. If - ``None``, no polymorphic discriminator is generated. - :param aliasname: name of the :func:`~sqlalchemy.sql.expression.alias()` - construct generated. - :param cast_nulls: if True, non-existent columns, which are represented as labeled - NULLs, will be passed into CAST. This is a legacy behavior that is problematic - on some backends such as Oracle - in which case it can be set to False. - - """ - - colnames = util.OrderedSet() - colnamemaps = {} - types = {} - for key in table_map.keys(): - table = table_map[key] - - # mysql doesnt like selecting from a select; - # make it an alias of the select - if isinstance(table, sql.Select): - table = table.alias() - table_map[key] = table - - m = {} - for c in table.c: - colnames.add(c.key) - m[c.key] = c - types[c.key] = c.type - colnamemaps[table] = m - - def col(name, table): - try: - return colnamemaps[table][name] - except KeyError: - if cast_nulls: - return sql.cast(sql.null(), types[name]).label(name) - else: - return sql.type_coerce(sql.null(), types[name]).label(name) - - result = [] - for type, table in table_map.iteritems(): - 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)], - from_obj=[table])) - else: - result.append(sql.select([col(name, table) for name in colnames], - from_obj=[table])) - return sql.union_all(*result).alias(aliasname) - -def identity_key(*args, **kwargs): - """Get an identity key. - - Valid call signatures: - - * ``identity_key(class, ident)`` - - class - mapped class (must be a positional argument) - - ident - primary key, if the key is composite this is a tuple - - - * ``identity_key(instance=instance)`` - - instance - object instance (must be given as a keyword arg) - - * ``identity_key(class, row=row)`` - - class - mapped class (must be a positional argument) - - row - result proxy row (must be given as a keyword arg) - - """ - if args: - if len(args) == 1: - class_ = args[0] - try: - row = kwargs.pop("row") - except KeyError: - ident = kwargs.pop("ident") - elif len(args) == 2: - class_, ident = args - elif len(args) == 3: - class_, ident = args - else: - 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.keys())) - mapper = class_mapper(class_) - if "ident" in locals(): - return mapper.identity_key_from_primary_key(ident) - return mapper.identity_key_from_row(row) - instance = kwargs.pop("instance") - if kwargs: - raise sa_exc.ArgumentError("unknown keyword arguments: %s" - % ", ".join(kwargs.keys())) - mapper = object_mapper(instance) - return mapper.identity_key_from_instance(instance) - -class ORMAdapter(sql_util.ColumnAdapter): - """Extends ColumnAdapter to accept ORM entities. - - The selectable is extracted from the given entity, - and the AliasedClass if any is referenced. - - """ - def __init__(self, entity, equivalents=None, - chain_to=None, adapt_required=False): - self.mapper, selectable, is_aliased_class = _entity_info(entity) - if is_aliased_class: - self.aliased_class = entity - else: - self.aliased_class = None - sql_util.ColumnAdapter.__init__(self, selectable, - equivalents, chain_to, - adapt_required=adapt_required) - - def replace(self, elem): - entity = elem._annotations.get('parentmapper', None) - if not entity or entity.isa(self.mapper): - return sql_util.ColumnAdapter.replace(self, elem) - else: - return None - -class AliasedClass(object): - """Represents an "aliased" form of a mapped class for usage with Query. - - The ORM equivalent of a :func:`sqlalchemy.sql.expression.alias` - construct, this object mimics the mapped class using a - __getattr__ scheme and maintains a reference to a - real :class:`~sqlalchemy.sql.expression.Alias` object. - - Usage is via the :class:`~sqlalchemy.orm.aliased()` synonym:: - - # find all pairs of users with the same name - user_alias = aliased(User) - session.query(User, user_alias).\\ - join((user_alias, User.id > user_alias.id)).\\ - filter(User.name==user_alias.name) - - """ - def __init__(self, cls, alias=None, name=None): - self.__mapper = _class_to_mapper(cls) - self.__target = self.__mapper.class_ - if alias is None: - alias = self.__mapper._with_polymorphic_selectable.alias(name=name) - self.__adapter = sql_util.ClauseAdapter(alias, - equivalents=self.__mapper._equivalent_columns) - self.__alias = alias - # used to assign a name to the RowTuple object - # returned by Query. - self._sa_label_name = name - self.__name__ = 'AliasedClass_' + str(self.__target) - - def __getstate__(self): - return { - 'mapper':self.__mapper, - 'alias':self.__alias, - 'name':self._sa_label_name - } - - def __setstate__(self, state): - self.__mapper = state['mapper'] - self.__target = self.__mapper.class_ - alias = state['alias'] - self.__adapter = sql_util.ClauseAdapter(alias, - equivalents=self.__mapper._equivalent_columns) - self.__alias = alias - name = state['name'] - self._sa_label_name = name - self.__name__ = 'AliasedClass_' + str(self.__target) - - def __adapt_element(self, elem): - return self.__adapter.traverse(elem).\ - _annotate({ - 'parententity': self, - 'parentmapper':self.__mapper} - ) - - def __adapt_prop(self, existing, key): - comparator = existing.comparator.adapted(self.__adapt_element) - - queryattr = attributes.QueryableAttribute(self, key, - impl=existing.impl, parententity=self, comparator=comparator) - setattr(self, key, queryattr) - return queryattr - - def __getattr__(self, key): - for base in self.__target.__mro__: - try: - attr = object.__getattribute__(base, key) - except AttributeError: - continue - else: - break - else: - raise AttributeError(key) - - if isinstance(attr, attributes.QueryableAttribute): - return self.__adapt_prop(attr, key) - elif hasattr(attr, 'func_code'): - is_method = getattr(self.__target, key, None) - if is_method and is_method.im_self is not None: - return util.types.MethodType(attr.im_func, self, self) - else: - return None - elif hasattr(attr, '__get__'): - ret = attr.__get__(None, self) - if isinstance(ret, PropComparator): - return ret.adapted(self.__adapt_element) - return ret - else: - return attr - - def __repr__(self): - return '<AliasedClass at 0x%x; %s>' % ( - id(self), self.__target.__name__) - -def aliased(element, alias=None, name=None): - if isinstance(element, expression.FromClause): - return element.alias(name) - else: - return AliasedClass(element, alias=alias, name=name) - -def _orm_annotate(element, exclude=None): - """Deep copy the given ClauseElement, annotating each element with the - "_orm_adapt" flag. - - Elements within the exclude collection will be cloned but not annotated. - - """ - return sql_util._deep_annotate(element, {'_orm_adapt':True}, exclude) - -_orm_deannotate = sql_util._deep_deannotate - -class _ORMJoin(expression.Join): - """Extend Join to support ORM constructs as input.""" - - __visit_name__ = expression.Join.__visit_name__ - - def __init__(self, left, right, onclause=None, - isouter=False, join_to_left=True): - adapt_from = None - - if hasattr(left, '_orm_mappers'): - left_mapper = left._orm_mappers[1] - if join_to_left: - adapt_from = left.right - else: - left_mapper, left, left_is_aliased = _entity_info(left) - if join_to_left and (left_is_aliased or not left_mapper): - adapt_from = left - - right_mapper, right, right_is_aliased = _entity_info(right) - if right_is_aliased: - adapt_to = right - else: - adapt_to = None - - if left_mapper or right_mapper: - self._orm_mappers = (left_mapper, right_mapper) - - if isinstance(onclause, basestring): - prop = left_mapper.get_property(onclause) - elif isinstance(onclause, attributes.QueryableAttribute): - if adapt_from is None: - adapt_from = onclause.__clause_element__() - prop = onclause.property - elif isinstance(onclause, MapperProperty): - prop = onclause - else: - prop = None - - if prop: - pj, sj, source, dest, \ - secondary, target_adapter = prop._create_joins( - source_selectable=adapt_from, - dest_selectable=adapt_to, - source_polymorphic=True, - dest_polymorphic=True, - of_type=right_mapper) - - if sj is not None: - left = sql.join(left, secondary, pj, isouter) - onclause = sj - else: - onclause = pj - self._target_adapter = target_adapter - - expression.Join.__init__(self, left, right, onclause, isouter) - - def join(self, right, onclause=None, isouter=False, join_to_left=True): - return _ORMJoin(self, right, onclause, isouter, join_to_left) - - def outerjoin(self, right, onclause=None, join_to_left=True): - return _ORMJoin(self, right, onclause, True, join_to_left) - -def join(left, right, onclause=None, isouter=False, join_to_left=True): - """Produce an inner join between left and right clauses. - - In addition to the interface provided by - :func:`~sqlalchemy.sql.expression.join()`, left and right may be mapped - classes or AliasedClass instances. The onclause may be a - string name of a relationship(), or a class-bound descriptor - representing a relationship. - - join_to_left indicates to attempt aliasing the ON clause, - in whatever form it is passed, to the selectable - passed as the left side. If False, the onclause - is used as is. - - """ - return _ORMJoin(left, right, onclause, isouter, join_to_left) - -def outerjoin(left, right, onclause=None, join_to_left=True): - """Produce a left outer join between left and right clauses. - - In addition to the interface provided by - :func:`~sqlalchemy.sql.expression.outerjoin()`, left and right may be - mapped classes or AliasedClass instances. The onclause may be a string - name of a relationship(), or a class-bound descriptor representing a - relationship. - - """ - return _ORMJoin(left, right, onclause, True, join_to_left) - -def with_parent(instance, prop): - """Create filtering criterion that relates this query's primary entity - to the given related instance, using established :func:`.relationship()` - configuration. - - The SQL rendered is the same as that rendered when a lazy loader - would fire off from the given parent on that attribute, meaning - that the appropriate state is taken from the parent object in - Python without the need to render joins to the parent table - in the rendered statement. - - As of 0.6.4, this method accepts parent instances in all - persistence states, including transient, persistent, and detached. - Only the requisite primary key/foreign key attributes need to - be populated. Previous versions didn't work with transient - instances. - - :param instance: - An instance which has some :func:`.relationship`. - - :param property: - String property name, or class-bound attribute, which indicates - what relationship from the instance should be used to reconcile the - parent/child relationship. - - """ - if isinstance(prop, basestring): - mapper = object_mapper(instance) - prop = mapper.get_property(prop) - elif isinstance(prop, attributes.QueryableAttribute): - prop = prop.property - - return prop.compare(operators.eq, - instance, - value_is_parent=True) - - -def _entity_info(entity, compile=True): - """Return mapping information given a class, mapper, or AliasedClass. - - Returns 3-tuple of: mapper, mapped selectable, boolean indicating if this - is an aliased() construct. - - If the given entity is not a mapper, mapped class, or aliased construct, - returns None, the entity, False. This is typically used to allow - unmapped selectables through. - - """ - if isinstance(entity, AliasedClass): - return entity._AliasedClass__mapper, entity._AliasedClass__alias, True - - if isinstance(entity, mapperlib.Mapper): - mapper = entity - - elif isinstance(entity, type): - class_manager = attributes.manager_of_class(entity) - - if class_manager is None: - return None, entity, False - - mapper = class_manager.mapper - else: - return None, entity, False - - if compile and mapperlib.module._new_mappers: - mapperlib.configure_mappers() - return mapper, mapper._with_polymorphic_selectable, False - -def _entity_descriptor(entity, key): - """Return a class attribute given an entity and string name. - - May return :class:`.InstrumentedAttribute` or user-defined - attribute. - - """ - if not isinstance(entity, (AliasedClass, type)): - entity = entity.class_ - - try: - return getattr(entity, key) - except AttributeError: - raise sa_exc.InvalidRequestError( - "Entity '%s' has no property '%s'" % - (entity, key) - ) - -def _orm_columns(entity): - mapper, selectable, is_aliased_class = _entity_info(entity) - if isinstance(selectable, expression.Selectable): - return [c for c in selectable.c] - else: - return [selectable] - -def _orm_selectable(entity): - mapper, selectable, is_aliased_class = _entity_info(entity) - return selectable - -def _attr_as_key(attr): - if hasattr(attr, 'key'): - return attr.key - else: - return expression._column_as_key(attr) - -def _is_aliased_class(entity): - return isinstance(entity, AliasedClass) - -_state_mapper = util.dottedgetter('manager.mapper') - -def object_mapper(instance): - """Given an object, return the primary Mapper associated with the object - instance. - - Raises UnmappedInstanceError if no mapping is configured. - - """ - try: - state = attributes.instance_state(instance) - return state.manager.mapper - except exc.UnmappedClassError: - raise exc.UnmappedInstanceError(instance) - except exc.NO_STATE: - raise exc.UnmappedInstanceError(instance) - -def class_mapper(class_, compile=True): - """Given a class, return the primary Mapper associated with the key. - - Raises UnmappedClassError if no mapping is configured. - - """ - - try: - class_manager = attributes.manager_of_class(class_) - mapper = class_manager.mapper - - except exc.NO_STATE: - raise exc.UnmappedClassError(class_) - - if compile and mapperlib.module._new_mappers: - mapperlib.configure_mappers() - return mapper - -def _class_to_mapper(class_or_mapper, compile=True): - if _is_aliased_class(class_or_mapper): - return class_or_mapper._AliasedClass__mapper - - elif isinstance(class_or_mapper, type): - try: - class_manager = attributes.manager_of_class(class_or_mapper) - mapper = class_manager.mapper - except exc.NO_STATE: - raise exc.UnmappedClassError(class_or_mapper) - elif isinstance(class_or_mapper, mapperlib.Mapper): - mapper = class_or_mapper - else: - raise exc.UnmappedClassError(class_or_mapper) - - if compile and mapperlib.module._new_mappers: - mapperlib.configure_mappers() - return mapper - -def has_identity(object): - state = attributes.instance_state(object) - return state.has_identity - -def _is_mapped_class(cls): - if isinstance(cls, (AliasedClass, mapperlib.Mapper)): - return True - if isinstance(cls, expression.ClauseElement): - return False - if isinstance(cls, type): - manager = attributes.manager_of_class(cls) - return manager and _INSTRUMENTOR in manager.info - return False - -def instance_str(instance): - """Return a string describing an instance.""" - - return state_str(attributes.instance_state(instance)) - -def state_str(state): - """Return a string describing an instance via its InstanceState.""" - - if state is None: - return "None" - else: - return '<%s at 0x%x>' % (state.class_.__name__, id(state.obj())) - -def state_class_str(state): - """Return a string describing an instance's class via its InstanceState.""" - - if state is None: - return "None" - else: - return '<%s>' % (state.class_.__name__, ) - -def attribute_str(instance, attribute): - return instance_str(instance) + "." + attribute - -def state_attribute_str(state, attribute): - return state_str(state) + "." + attribute - -def identity_equal(a, b): - if a is b: - return True - if a is None or b is None: - return False - try: - state_a = attributes.instance_state(a) - state_b = attributes.instance_state(b) - except exc.NO_STATE: - return False - if state_a.key is None or state_b.key is None: - return False - return state_a.key == state_b.key - |