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

📄 sqlobject.py

📁 Python的一个ORM,现在很火
💻 PY
📖 第 1 页 / 共 2 页
字号:
## Copyright (c) 2006, 2007 Canonical## Written by Gustavo Niemeyer <gustavo@niemeyer.net>## This file is part of Storm Object Relational Mapper.## Storm is free software; you can redistribute it and/or modify# it under the terms of the GNU Lesser General Public License as# published by the Free Software Foundation; either version 2.1 of# the License, or (at your option) any later version.## Storm is distributed in the hope that it will be useful,# but WITHOUT ANY WARRANTY; without even the implied warranty of# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the# GNU Lesser General Public License for more details.## You should have received a copy of the GNU Lesser General Public License# along with this program.  If not, see <http://www.gnu.org/licenses/>.#"""A SQLObject emulation layer for Storm.L{SQLObjectBase} is the central point of compatibility."""import refrom storm.properties import (    Unicode, Chars, Int, Bool, Float, DateTime, Date, TimeDelta)from storm.references import Reference, ReferenceSetfrom storm.properties import SimpleProperty, PropertyPublisherMetafrom storm.variables import Variablefrom storm.exceptions import StormErrorfrom storm.info import get_cls_infofrom storm.store import Storefrom storm.base import Stormfrom storm.expr import SQL, SQLRaw, Desc, And, Or, Not, In, Likefrom storm.tz import tzutcfrom storm import Undef__all__ = ["SQLObjectBase", "StringCol", "IntCol", "BoolCol", "FloatCol",           "DateCol", "UtcDateTimeCol", "IntervalCol", "ForeignKey",           "SQLMultipleJoin", "SQLRelatedJoin", "DESC", "AND", "OR",           "NOT", "IN", "LIKE", "SQLConstant", "SQLObjectNotFound",           "CONTAINSSTRING"]DESC, AND, OR, NOT, IN, LIKE, SQLConstant = Desc, And, Or, Not, In, Like, SQL_IGNORED = object()class SQLObjectNotFound(StormError):    passclass SQLObjectStyle(object):    longID = False    def idForTable(self, table_name):        if self.longID:            return self.tableReference(table_name)        else:            return 'id'    def pythonClassToAttr(self, class_name):        return self._lowerword(class_name)    def instanceAttrToIDAttr(self, attr_name):        return attr_name + "ID"    def pythonAttrToDBColumn(self, attr_name):        return self._mixed_to_under(attr_name)    def dbColumnToPythonAttr(self, column_name):        return self._under_to_mixed(column_name)    def pythonClassToDBTable(self, class_name):        return class_name[0].lower()+self._mixed_to_under(class_name[1:])    def dbTableToPythonClass(self, table_name):        return table_name[0].upper()+self._under_to_mixed(table_name[1:])    def pythonClassToDBTableReference(self, class_name):        return self.tableReference(self.pythonClassToDBTable(class_name))    def tableReference(self, table_name):        return table_name+"_id"    def _mixed_to_under(self, name, _re=re.compile(r'[A-Z]+')):        if name.endswith('ID'):            return self._mixed_to_under(name[:-2]+"_id")        name = _re.sub(self._mixed_to_under_sub, name)        if name.startswith('_'):            return name[1:]        return name        def _mixed_to_under_sub(self, match):        m = match.group(0).lower()        if len(m) > 1:            return '_%s_%s' % (m[:-1], m[-1])        else:            return '_%s' % m    def _under_to_mixed(self, name, _re=re.compile('_.')):        if name.endswith('_id'):            return self._under_to_mixed(name[:-3] + "ID")        return _re.sub(self._under_to_mixed_sub, name)    def _under_to_mixed_sub(self, match):        return match.group(0)[1].upper()    @staticmethod    def _capword(s):        return s[0].upper() + s[1:]        @staticmethod    def _lowerword(s):        return s[0].lower() + s[1:]class SQLObjectMeta(PropertyPublisherMeta):    @staticmethod    def _get_attr(attr, bases, dict):        value = dict.get(attr)        if value is None:            for base in bases:                value = getattr(base, attr, None)                if value is not None:                    break        return value    def __new__(cls, name, bases, dict):        if Storm in bases or SQLObjectBase in bases:            # Do not parse abstract base classes.            return type.__new__(cls, name, bases, dict)        style = cls._get_attr("_style", bases, dict)        if style is None:            dict["_style"] = style = SQLObjectStyle()        table_name = cls._get_attr("_table", bases, dict)        if table_name is None:            table_name = style.pythonClassToDBTable(name)        id_name = cls._get_attr("_idName", bases, dict)        if id_name is None:            id_name = style.idForTable(table_name)        # Handle this later to call _parse_orderBy() on the created class.        default_order = cls._get_attr("_defaultOrder", bases, dict)        dict["__storm_table__"] = table_name        attr_to_prop = {}        for attr, prop in dict.items():            attr_to_prop[attr] = attr            if isinstance(prop, ForeignKey):                db_name = prop.kwargs.get("dbName", attr)                local_prop_name = style.instanceAttrToIDAttr(attr)                dict[local_prop_name] = local_prop = Int(db_name)                dict[attr] = Reference(local_prop,                                       "%s.<primary key>" % prop.foreignKey)                attr_to_prop[attr] = local_prop_name            elif isinstance(prop, PropertyAdapter):                db_name = prop.dbName or attr                method_name = prop.alternateMethodName                if method_name is None and prop.alternateID:                    method_name = "by" + db_name[0].upper() + db_name[1:]                if method_name is not None:                    def func(cls, key, attr=attr):                        store = cls._get_store()                        obj = store.find(cls, getattr(cls, attr) == key).one()                        if obj is None:                            raise SQLObjectNotFound                        return obj                    func.func_name = method_name                    dict[method_name] = classmethod(func)        id_type = dict.get("_idType", int)        id_cls = {int: Int, str: Chars, unicode: AutoUnicode}[id_type]        dict[id_name] = id_cls(primary=True)        # Notice that obj is the class since this is the metaclass.        obj = super(SQLObjectMeta, cls).__new__(cls, name, bases, dict)        property_registry = obj._storm_property_registry        property_registry.add_property(obj, getattr(obj, id_name),                                       "<primary key>")        for fake_name, real_name in attr_to_prop.items():            prop = getattr(obj, real_name)            if fake_name != real_name:                property_registry.add_property(obj, prop, fake_name)            attr_to_prop[fake_name] = prop        obj._attr_to_prop = attr_to_prop        if default_order is not None:            cls_info = get_cls_info(obj)            cls_info.default_order = obj._parse_orderBy(default_order)        return objclass DotQ(object):    """A descriptor that mimics the SQLObject 'Table.q' syntax"""    def __get__(self, obj, cls=None):        return BoundDotQ(cls)class BoundDotQ(object):    def __init__(self, cls):        self._cls = cls    def __getattr__(self, attr):        if attr.startswith('__'):            raise AttributeError(attr)        elif attr == 'id':            cls_info = get_cls_info(self._cls)            return cls_info.primary_key[0]        else:            return getattr(self._cls, attr)class SQLObjectBase(Storm):    """The root class of all SQLObject-emulating classes in your application.    The general strategy for using Storm's SQLObject emulation layer    is to create an application-specific subclass of SQLObjectBase    (probably named "SQLObject") that provides an implementation of    _get_store to return an instance of L{storm.store.Store}. It may    even be implemented as returning a global L{Store} instance. Then    all database classes should subclass that class.    """    __metaclass__ = SQLObjectMeta    q = DotQ()    def __init__(self, *args, **kwargs):        self._get_store().add(self)        self._create(None, **kwargs)    def __storm_loaded__(self):        self._init(None)    def _init(self, id, *args, **kwargs):        pass    def _create(self, _id_, **kwargs):        self.set(**kwargs)        self._init(None)    def set(self, **kwargs):        for attr, value in kwargs.iteritems():            setattr(self, attr, value)    def destroySelf(self):        Store.of(self).remove(self)    @staticmethod

⌨️ 快捷键说明

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