Python - 动手写个ORM
2016-05-13 08:41
477 查看
Python - 动手写个ORM
任务:
模拟简单的ORM - Object Relational Mapping为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
参考:使用元类
相关文章推荐
- Python 依赖库
- Python笔记:除、取整、取余、乘方
- Python笔记:加减乘除,格式化字符串
- ipython的两种安装方式
- 《Python核心编程》第7章 习题
- Python-continue的使用和if的位置
- ubuntu为Python添加默认搜索路径
- Python:统计系统剩余内存
- python基于phantomjs实现导入图片
- Python生成图片验证码
- 使用 Python 切割图片
- python subprocess模块
- python gevent 模块
- 使用Python管理Azure(1):基础配置
- DayDayUP_Python自学记录[15]_python execl 读写进阶
- 使用Python管理Azure(1):基础配置
- Python2.7 Queue模块学习
- python之cpu性能检测脚本
- 批量更改文件的扩展名
- Python 性能比较和做函数级单元测试的方法