zoukankan      html  css  js  c++  java
  • Python

    Python - 动手写个ORM

    任务:

    1. 模拟简单的ORM - Object Relational Mapping
    2. 为model添加create方法

    代码很简单,直接上

    字段类型类

    
    class Field(object):
        """docstring for Field"""
    
        def __init__(self, field_type, default, max_length,  * arg):
            super().__init__()
            self.default = default
            self.max_length = max_length
            self.field_type = field_type
    
    
    class CharField(Field):
        """docstring for CharField"""
    
        def __init__(self, max_length=100, *arg):
            super().__init__('char', '', max_length)
    
    
    class DateField(Field):
        """docstring for DateField"""
    
        def __init__(self, default='now', *arg):
            if(default == 'now'):
                from datetime import datetime
                self.default = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
            else:
                self.default = default
            super().__init__('datetime', self.default, None)
    
    
    class IntField(Field):
        """docstring for IntField"""
    
        def __init__(self, default=0, *arg):
            super().__init__('int', 0, 8)
    
    

    很关键的MetaClass

    
    class ModelMetaClass(type):
        """docstring for ModelMetaClass"""
    
        def __new__(cls, name, bases, attrs):
            print('2. ModelMetaClass __new__')
            mapping = {}
            # mapping = dict()
            for k, v in attrs.items():
                if(isinstance(v, Field)):
                    mapping[k] = v
            for k, v in mapping.items():
                del attrs[k]
    
            # 挂到实例上
            # attrs['mapping'] = mapping
            cls_obj = type.__new__(cls, name, bases, attrs)
    
            # 这里为了测试效果简单的将需要的信息添加到类的动态属性上
            cls_obj.mapping = mapping
            cls_obj.table = name
    
            return cls_obj
    
    # 如果子类中指定metaclass那么必须从父类的meta继承以维持正确的调用顺序
    class NewsMetaClass(ModelMetaClass):
        """docstring for NewsMetaClass"""
        print('1. NewsMetaClass __new__')
    
        def __new__(cls, name, bases, attrs):
            # do anything you want
    
            # attrs['create'] = NewsMetaClass.create
    
            clsobj = super().__new__(cls, name, bases, attrs)
            return clsobj
    

    Model类, 注意metaclass的设定

    class Model(object, metaclass=ModelMetaClass):
        """docstring for Model"""
    
        def __init__(self, *arg):
            super(Model, self).__init__()
            self.arg = arg
    
        @classmethod
        def create(cls, **kwargs):
            fields = []
            params = []
            args = []
    
            for k, v in cls.mapping.items():
                fields.append(k)
                params.append('?')
                args.append(kwargs[k])
    
            sql = 'insert into %s (%s) values(%s)' % (cls.table, ','.join(fields), ','.join(params))
            param = ','.join(args)
            print('SQL: %s' % (sql))
            print('args: %s' % param)
            # exec the sql
    
    
    class News(Model, metaclass=NewsMetaClass):
        """docstring for News"""
        title = CharField(max_length=100)
        content = CharField(max_length=500)
        publish_date = DateField(default="now")
        read_count = IntField(default=0)
    

    测试效果

    from datetime import datetime
    News.create(title='test', content='asdf', read_count='0', publish_date=datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
    
    # SQL: insert into News (publish_date,content,title,read_count) values(?,?,?,?)
    # args: 2016-05-16 22:39:54,asdf,test,0
    
    

    参考:使用元类

  • 相关阅读:
    可怕的沉默
    我排着队 拿着号码牌
    移动改名正在运行的程序
    C# 注册热键
    c#通过编码检查是否有PendingChanges没有签入
    c#读取带命名空间的xml
    自动查找并关闭窗口
    C# 应用微软的Visual Studio International Pack 类库提取汉字拼音首字母
    C#执行DOS命令(CMD命令) (转)
    asp.net 文件下载,有进度条
  • 原文地址:https://www.cnblogs.com/wancy86/p/python_orm.html
Copyright © 2011-2022 走看看