⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mapper.py

📁 SQLAlchemy. 经典的Python ORM框架。学习必看。
💻 PY
📖 第 1 页 / 共 5 页
字号:
# orm/mapper.py# Copyright (C) 2005, 2006, 2007, 2008 Michael Bayer mike_mp@zzzcomputing.com## This module is part of SQLAlchemy and is released under# the MIT License: http://www.opensource.org/licenses/mit-license.php"""Defines the [sqlalchemy.orm.mapper#Mapper] class, the central configurationalunit which associates a class with a database table.This is a semi-private module; the main configurational API of the ORM isavailable in [sqlalchemy.orm#]."""import weakreffrom itertools import chainfrom sqlalchemy import sql, util, exceptions, loggingfrom sqlalchemy.sql import expression, visitors, operators, util as sqlutilfrom sqlalchemy.sql.expression import _corresponding_column_or_errorfrom sqlalchemy.orm import sync, attributesfrom sqlalchemy.orm.util import ExtensionCarrier, create_row_adapter, state_str, instance_strfrom sqlalchemy.orm.interfaces import MapperProperty, EXT_CONTINUE, PropComparator__all__ = ['Mapper', 'class_mapper', 'object_mapper', '_mapper_registry']_mapper_registry = weakref.WeakKeyDictionary()# a list of MapperExtensions that will be installed in all mappers by defaultglobal_extensions = []# a constant returned by _get_attr_by_column to indicate# this mapper is not handling an attribute for a particular# columnNO_ATTRIBUTE = object()# lock used to synchronize the "mapper compile" step_COMPILE_MUTEX = util.threading.Lock()# initialize these two lazilyColumnProperty = NoneSynonymProperty = Noneclass Mapper(object):    """Define the correlation of class attributes to database table    columns.    Instances of this class should be constructed via the    [sqlalchemy.orm#mapper()] function.    """    def __init__(self,                 class_,                 local_table,                 properties = None,                 primary_key = None,                 non_primary = False,                 inherits = None,                 inherit_condition = None,                 inherit_foreign_keys = None,                 extension = None,                 order_by = False,                 allow_column_override = False,                 entity_name = None,                 always_refresh = False,                 version_id_col = None,                 polymorphic_on=None,                 _polymorphic_map=None,                 polymorphic_identity=None,                 polymorphic_fetch=None,                 concrete=False,                 select_table=None,                 allow_null_pks=False,                 batch=True,                 column_prefix=None,                 include_properties=None,                 exclude_properties=None,                 eager_defaults=False):        """Construct a new mapper.        Mappers are normally constructed via the [sqlalchemy.orm#mapper()]        function.  See for details.        """        if not issubclass(class_, object):            raise exceptions.ArgumentError("Class '%s' is not a new-style class" % class_.__name__)        for table in (local_table, select_table):            if table is not None and isinstance(table, expression._SelectBaseMixin):                # some db's, noteably postgres, dont want to select from a select                # without an alias.  also if we make our own alias internally, then                # the configured properties on the mapper are not matched against the alias                # we make, theres workarounds but it starts to get really crazy (its crazy enough                # the SQL that gets generated) so just require an alias                raise exceptions.ArgumentError("Mapping against a Select object requires that it has a name.  Use an alias to give it a name, i.e. s = select(...).alias('myselect')")        self.class_ = class_        self.entity_name = entity_name        self.primary_key_argument = primary_key        self.non_primary = non_primary        self.order_by = order_by        self.always_refresh = always_refresh        self.version_id_col = version_id_col        self.concrete = concrete        self.single = False        self.inherits = inherits        self.select_table = select_table        self.local_table = local_table        self.inherit_condition = inherit_condition        self.inherit_foreign_keys = inherit_foreign_keys        self.extension = extension        self._init_properties = properties or {}        self.allow_column_override = allow_column_override        self.allow_null_pks = allow_null_pks        self.delete_orphans = []        self.batch = batch        self.eager_defaults = eager_defaults        self.column_prefix = column_prefix        self.polymorphic_on = polymorphic_on        self._eager_loaders = util.Set()        self._row_translators = {}        self._dependency_processors = []        self._clause_adapter = None        # our 'polymorphic identity', a string name that when located in a result set row        # indicates this Mapper should be used to construct the object instance for that row.        self.polymorphic_identity = polymorphic_identity        if polymorphic_fetch not in (None, 'union', 'select', 'deferred'):            raise exceptions.ArgumentError("Invalid option for 'polymorphic_fetch': '%s'" % polymorphic_fetch)        if polymorphic_fetch is None:            self.polymorphic_fetch = (self.select_table is None) and 'select' or 'union'        else:            self.polymorphic_fetch = polymorphic_fetch        # a dictionary of 'polymorphic identity' names, associating those names with        # Mappers that will be used to construct object instances upon a select operation.        if _polymorphic_map is None:            self.polymorphic_map = {}        else:            self.polymorphic_map = _polymorphic_map        self.columns = self.c = util.OrderedProperties()        self.include_properties = include_properties        self.exclude_properties = exclude_properties        # a set of all mappers which inherit from this one.        self._inheriting_mappers = util.Set()        # a second mapper that is used for selecting, if the "select_table" argument        # was sent to this mapper.        self.__surrogate_mapper = None        self.__props_init = False        self.__should_log_info = logging.is_info_enabled(self.logger)        self.__should_log_debug = logging.is_debug_enabled(self.logger)        self._compile_class()        self._compile_inheritance()        self._compile_extensions()        self._compile_tables()        self._compile_properties()        self._compile_pks()        self._compile_selectable()        self.__log("constructed")    def __log(self, msg):        if self.__should_log_info:            self.logger.info("(" + self.class_.__name__ + "|" + (self.entity_name is not None and "/%s" % self.entity_name or "") + (self.local_table and self.local_table.description or str(self.local_table)) + (not self.non_primary and "|non-primary" or "") + ") " + msg)    def __log_debug(self, msg):        if self.__should_log_debug:            self.logger.debug("(" + self.class_.__name__ + "|" + (self.entity_name is not None and "/%s" % self.entity_name or "") + (self.local_table and self.local_table.description or str(self.local_table)) + (not self.non_primary and "|non-primary" or "") + ") " + msg)    def _is_orphan(self, obj):        optimistic = has_identity(obj)        for (key,klass) in self.delete_orphans:            if attributes.has_parent(klass, obj, key, optimistic=optimistic):               return False        else:            if self.delete_orphans:                if not has_identity(obj):                    raise exceptions.FlushError("instance %s is an unsaved, pending instance and is an orphan (is not attached to %s)" %                    (                        obj,                        ", nor ".join(["any parent '%s' instance via that classes' '%s' attribute" % (klass.__name__, key) for (key,klass) in self.delete_orphans])                    ))                else:                    return True            else:                return False    def get_property(self, key, resolve_synonyms=False, raiseerr=True):        """return a MapperProperty associated with the given key."""        self.compile()        return self._get_property(key, resolve_synonyms=resolve_synonyms, raiseerr=raiseerr)    def _get_property(self, key, resolve_synonyms=False, raiseerr=True):        """private in-compilation version of get_property()."""        prop = self.__props.get(key, None)        if resolve_synonyms:            while isinstance(prop, SynonymProperty):                prop = self.__props.get(prop.name, None)        if prop is None and raiseerr:            raise exceptions.InvalidRequestError("Mapper '%s' has no property '%s'" % (str(self), key))        return prop    def iterate_properties(self):        self.compile()        return self.__props.itervalues()    iterate_properties = property(iterate_properties, doc="returns an iterator of all MapperProperty objects.")    def properties(self):        raise NotImplementedError("Public collection of MapperProperty objects is provided by the get_property() and iterate_properties accessors.")    properties = property(properties)    compiled = property(lambda self:self.__props_init, doc="return True if this mapper is compiled")    def dispose(self):        # disaable any attribute-based compilation        self.__props_init = True        try:            del self.class_.c        except AttributeError:            pass        if not self.non_primary and self.entity_name in self._class_state.mappers:            del self._class_state.mappers[self.entity_name]        if not self._class_state.mappers:            attributes.unregister_class(self.class_)    def compile(self):        """Compile this mapper into its final internal format.        """        if self.__props_init:            return self        _COMPILE_MUTEX.acquire()        try:            # double-check inside mutex            if self.__props_init:                return self            # initialize properties on all mappers            for mapper in list(_mapper_registry):                if not mapper.__props_init:                    mapper.__initialize_properties()            return self        finally:            _COMPILE_MUTEX.release()    def __initialize_properties(self):        """Call the ``init()`` method on all ``MapperProperties``        attached to this mapper.        This happens after all mappers have completed compiling        everything else up until this point, so that all dependencies        are fully available.        """        self.__log("_initialize_properties() started")        l = [(key, prop) for key, prop in self.__props.iteritems()]        for key, prop in l:            self.__log("initialize prop " + key)            if getattr(prop, 'key', None) is None:                prop.init(key, self)        self.__log("_initialize_properties() complete")        self.__props_init = True    def _compile_extensions(self):        """Go through the global_extensions list as well as the list        of ``MapperExtensions`` specified for this ``Mapper`` and        creates a linked list of those extensions.        """

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -