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

📄 schema.py

📁 SQLAlchemy. 经典的Python ORM框架。学习必看。
💻 PY
📖 第 1 页 / 共 5 页
字号:
# schema.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"""The schema module provides the building blocks for database metadata.Each element within this module describes a database entitywhich can be created and dropped, or is otherwise part of such an entity.Examples include tables, columns, sequences, and indexes.All entities are subclasses of [sqlalchemy.schema#SchemaItem], and asdefined in this module they are intended to be agnostic of anyvendor-specific constructs.A collection of entities are grouped into a unit called [sqlalchemy.schema#MetaData].MetaData serves as a logical grouping of schema elements, and can alsobe associated with an actual database connection such that operationsinvolving the contained elements can contact the database as needed.Two of the elements here also build upon their "syntactic" counterparts,which are defined in [sqlalchemy.sql.expression#], specifically [sqlalchemy.schema#Table]and [sqlalchemy.schema#Column].  Since these objects are part of theSQL expression language, they are usable as components in SQL expressions."""import re, inspectfrom sqlalchemy import types, exceptions, util, databasesfrom sqlalchemy.sql import expression, visitorsURL = None__all__ = ['SchemaItem', 'Table', 'Column', 'ForeignKey', 'Sequence', 'Index',           'ForeignKeyConstraint', 'PrimaryKeyConstraint', 'CheckConstraint',           'UniqueConstraint', 'DefaultGenerator', 'Constraint', 'MetaData',           'ThreadLocalMetaData', 'SchemaVisitor', 'PassiveDefault',           'ColumnDefault', 'DDL']class SchemaItem(object):    """Base class for items that define a database schema."""    __metaclass__ = expression._FigureVisitName    def _init_items(self, *args):        """Initialize the list of child items for this SchemaItem."""        for item in args:            if item is not None:                item._set_parent(self)    def _set_parent(self, parent):        """Associate with this SchemaItem's parent object."""        raise NotImplementedError()    def get_children(self, **kwargs):        """used to allow SchemaVisitor access"""        return []    def __repr__(self):        return "%s()" % self.__class__.__name__    def bind(self):        """Return the connectable associated with this SchemaItem."""        m = self.metadata        return m and m.bind or None    bind = property(bind)    def info(self):        try:            return self._info        except AttributeError:            self._info = {}            return self._info    info = property(info)def _get_table_key(name, schema):    if schema is None:        return name    else:        return schema + "." + nameclass _TableSingleton(expression._FigureVisitName):    """A metaclass used by the ``Table`` object to provide singleton behavior."""    def __call__(self, name, metadata, *args, **kwargs):        schema = kwargs.get('schema', None)        useexisting = kwargs.pop('useexisting', False)        mustexist = kwargs.pop('mustexist', False)        key = _get_table_key(name, schema)        try:            table = metadata.tables[key]            if not useexisting and table._cant_override(*args, **kwargs):                raise exceptions.InvalidRequestError("Table '%s' is already defined for this MetaData instance.  Specify 'useexisting=True' to redefine options and columns on an existing Table object." % key)            else:                table._init_existing(*args, **kwargs)            return table        except KeyError:            if mustexist:                raise exceptions.InvalidRequestError("Table '%s' not defined" % (key))            try:                return type.__call__(self, name, metadata, *args, **kwargs)            except:                if key in metadata.tables:                    del metadata.tables[key]                raiseclass Table(SchemaItem, expression.TableClause):    """Represent a relational database table."""    __metaclass__ = _TableSingleton    ddl_events = ('before-create', 'after-create', 'before-drop', 'after-drop')    def __init__(self, name, metadata, *args, **kwargs):        """Construct a Table.        Table objects can be constructed directly.  Arguments        are:        name          The name of this table, exactly as it appears, or will          appear, in the database.          This property, along with the *schema*, indicates the          *singleton identity* of this table.          Further tables constructed with the same name/schema          combination will return the same Table instance.        \*args          Should contain a listing of the Column objects for this table.        \**kwargs          kwargs include:          schema            The *schema name* for this table, which is            required if the table resides in a schema other than the            default selected schema for the engine's database            connection.  Defaults to ``None``.          autoload            Defaults to False: the Columns for this table should be            reflected from the database.  Usually there will be no            Column objects in the constructor if this property is set.          autoload_with            if autoload==True, this is an optional Engine or Connection            instance to be used for the table reflection.  If ``None``,            the underlying MetaData's bound connectable will be used.          include_columns            A list of strings indicating a subset of columns to be            loaded via the ``autoload`` operation; table columns who            aren't present in this list will not be represented on the resulting            ``Table`` object.  Defaults to ``None`` which indicates all            columns should be reflected.          info            Defaults to {}: A space to store application specific data;            this must be a dictionary.          mustexist            Defaults to False: indicates that this Table must already            have been defined elsewhere in the application, else an            exception is raised.          useexisting            Defaults to False: indicates that if this Table was            already defined elsewhere in the application, disregard            the rest of the constructor arguments.          owner            Defaults to None: optional owning user of this table.            useful for databases such as Oracle to aid in table            reflection.          quote            Defaults to False: indicates that the Table identifier            must be properly escaped and quoted before being sent to            the database. This flag overrides all other quoting            behavior.          quote_schema            Defaults to False: indicates that the Namespace identifier            must be properly escaped and quoted before being sent to            the database. This flag overrides all other quoting            behavior.        """        super(Table, self).__init__(name)        self.metadata = metadata        self.schema = kwargs.pop('schema', None)        self.owner = kwargs.pop('owner', None)        self.indexes = util.Set()        self.constraints = util.Set()        self._columns = expression.ColumnCollection()        self.primary_key = PrimaryKeyConstraint()        self._foreign_keys = util.OrderedSet()        self.ddl_listeners = util.defaultdict(list)        self.kwargs = {}        if self.schema is not None:            self.fullname = "%s.%s" % (self.schema, self.name)        else:            self.fullname = self.name        autoload = kwargs.pop('autoload', False)        autoload_with = kwargs.pop('autoload_with', None)        include_columns = kwargs.pop('include_columns', None)        self._set_parent(metadata)        # load column definitions from the database if 'autoload' is defined        # we do it after the table is in the singleton dictionary to support        # circular foreign keys        if autoload:            if autoload_with:                autoload_with.reflecttable(self, include_columns=include_columns)            else:                _bind_or_error(metadata).reflecttable(self, include_columns=include_columns)        # initialize all the column, etc. objects.  done after        # reflection to allow user-overrides        self.__post_init(*args, **kwargs)        def _init_existing(self, *args, **kwargs):        autoload = kwargs.pop('autoload', False)        autoload_with = kwargs.pop('autoload_with', None)        schema = kwargs.pop('schema', None)        if schema and schema != self.schema:            raise exceptions.ArgumentError("Can't change schema of existing table from '%s' to '%s'", (self.schema, schema))        owner = kwargs.pop('owner', None)        if owner:            if not self.owner:                self.owner = owner            elif owner != self.owner:                raise exceptions.ArgumentError("Can't change owner of existing table from '%s' to '%s'", (self.owner, owner))            include_columns = kwargs.pop('include_columns', None)        if include_columns:            for c in self.c:                if c.name not in include_columns:                    self.c.remove(c)        self.__post_init(*args, **kwargs)        def _cant_override(self, *args, **kwargs):        """return True if the given arguments cannot be sent to a table that already exists.                the 'useexisting' flag overrides this.        """        return bool(args) or bool(util.Set(kwargs).difference(['autoload', 'autoload_with', 'schema', 'owner']))            def __post_init(self, *args, **kwargs):        self.quote = kwargs.pop('quote', False)        self.quote_schema = kwargs.pop('quote_schema', False)        if kwargs.get('info'):            self._info = kwargs.pop('info')        # validate remaining kwargs that they all specify DB prefixes        if len([k for k in kwargs if not re.match(r'^(?:%s)_' % '|'.join(databases.__all__), k)]):            raise TypeError("Invalid argument(s) for Table: %s" % repr(kwargs.keys()))        self.kwargs.update(kwargs)        self._init_items(*args)            def key(self):        return _get_table_key(self.name, self.schema)    key = property(key)    def _export_columns(self, columns=None):        # override FromClause's collection initialization logic; Table implements it differently        pass    def _set_primary_key(self, pk):        if getattr(self, '_primary_key', None) in self.constraints:            self.constraints.remove(self._primary_key)        self._primary_key = pk        self.constraints.add(pk)    def primary_key(self):        return self._primary_key    primary_key = property(primary_key, _set_primary_key)    def __repr__(self):        return "Table(%s)" % ', '.join(            [repr(self.name)] + [repr(self.metadata)] +            [repr(x) for x in self.columns] +            ["%s=%s" % (k, repr(getattr(self, k))) for k in ['schema']])    def __str__(self):        return _get_table_key(self.description, self.schema)    def append_column(self, column):        """Append a ``Column`` to this ``Table``."""        column._set_parent(self)    def append_constraint(self, constraint):        """Append a ``Constraint`` to this ``Table``."""        constraint._set_parent(self)    def append_ddl_listener(self, event, listener):        """Append a DDL event listener to this ``Table``.        The ``listener`` callable will be triggered when this ``Table`` is        created or dropped, either directly before or after the DDL is issued        to the database.  The listener may modify the Table, but may not abort        the event itself.        Arguments are:        event          One of ``Table.ddl_events``; e.g. 'before-create', 'after-create',          'before-drop' or 'after-drop'.        listener          A callable, invoked with three positional arguments:          event            The event currently being handled          schema_item            The ``Table`` object being created or dropped          bind            The ``Connection`` bueing used for DDL execution.        Listeners are added to the Table's ``ddl_listeners`` attribute.        """        if event not in self.ddl_events:            raise LookupError(event)        self.ddl_listeners[event].append(listener)    def _set_parent(self, metadata):        metadata.tables[_get_table_key(self.name, self.schema)] = self        self.metadata = metadata

⌨️ 快捷键说明

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