码迷,mamicode.com
首页 > 编程语言 > 详细

浅谈python web框架中的orm设计

时间:2015-09-22 01:25:08      阅读:350      评论:0      收藏:0      [点我收藏+]

标签:

看了一下廖雪峰的那个web框架,其实就是封装了web.py,请求使用异步并将aiomysql做为MySQL数据库提供了异步IO的驱动,前端部分则整合了jinja.其中最难的应该是orm部分了。

下面是orm一个简单的例子。

class User(Model):
    __table__ = users

    id = StringField(primary_key=True, default=next_id, ddl=varchar(50))
    email = StringField(ddl=varchar(50))
    passwd = StringField(ddl=varchar(50))
    admin = BooleanField()
    name = StringField(ddl=varchar(50))
    image = StringField(ddl=varchar(500))
    created_at = FloatField(default=time.time)

整体来看这是一个为User的简单table,集成了Model类。然后字段则是各种类型Field。

1.先来看看字段,也就是Field部分。Field部分比较简单,继承了object,然后初始化一些字段,其实没什么好说的。在字段赋值时,参数以dict格式传入,传入到哪里呢,本来type的dict是为none的,但下面这段代码用__new__改变了原来的type,而元类是创建类的类,因此,Field字段的参数,都会在ModelMetaclass类中做处理

class ModelMetaclass(type):

    def __new__(cls, name, bases, attrs):
        if name==Model:
            return type.__new__(cls, name, bases, attrs)
        tableName = attrs.get(__table__, None) or name
        logging.info(found model: %s (table: %s) % (name, tableName))
        mappings = dict()
        fields = []
        primaryKey = None
        for k, v in attrs.items():
            if isinstance(v, Field):
                logging.info(  found mapping: %s ==> %s % (k, v))
                mappings[k] = v
                if v.primary_key:
                    # 找到主键:
                    if primaryKey:
                        raise StandardError(Duplicate primary key for field: %s % k)
                    primaryKey = k
                else:
                    fields.append(k)
        if not primaryKey:
            raise StandardError(Primary key not found.)
        for k in mappings.keys():
            attrs.pop(k)
        escaped_fields = list(map(lambda f: `%s` % f, fields))
        attrs[__mappings__] = mappings # 保存属性和列的映射关系
        attrs[__table__] = tableName
        attrs[__primary_key__] = primaryKey # 主键属性名
        attrs[__fields__] = fields # 除主键外的属性名
        attrs[__select__] = select `%s`, %s from `%s` % (primaryKey, , .join(escaped_fields), tableName)
        attrs[__insert__] = insert into `%s` (%s, `%s`) values (%s) % (tableName, , .join(escaped_fields), primaryKey, create_args_string(len(escaped_fields) + 1))
        attrs[__update__] = update `%s` set %s where `%s`=? % (tableName, , .join(map(lambda f: `%s`=? % (mappings.get(f).name or f), fields)), primaryKey)
        attrs[__delete__] = delete from `%s` where `%s`=? % (tableName, primaryKey)
        return type.__new__(cls, name, bases, attrs)

而Model类相对简单,主要是为了初始化了get/set以及几个getvalue的函数,这一块根据自己需要看看就好。

class Model(dict, metaclass=ModelMetaclass):

    def __init__(self, **kw):
        super(Model, self).__init__(**kw)

    def __getattr__(self, key):
        try:
            return self[key]
        except KeyError:
            raise AttributeError(r"‘Model‘ object has no attribute ‘%s‘" % key)

    def __setattr__(self, key, value):
        self[key] = value

    def getValue(self, key):
        return getattr(self, key, None)

    def getValueOrDefault(self, key):
        value = getattr(self, key, None)
        if value is None:
            field = self.__mappings__[key]
            if field.default is not None:
                value = field.default() if callable(field.default) else field.default
                logging.debug(using default value for %s: %s % (key, str(value)))
                setattr(self, key, value)
        return value

    @classmethod
    @asyncio.coroutine
    def findNumber(cls, selectField, where=None, args=None):
         find number by select and where. 
        sql = [select %s _num_ from `%s` % (selectField, cls.__table__)]
        if where:
            sql.append(where)
            sql.append(where)
        rs = yield from select( .join(sql), args, 1)
        if len(rs) == 0:
            return None
        return rs[0][_num_]

....

@classmethod是为了将方法变成类方法,@asyncio.coroutine则是为了做异步处理。

 

浅谈python web框架中的orm设计

标签:

原文地址:http://www.cnblogs.com/alexkn/p/4827767.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!