Python - 动手写个ORM
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 - 动手写个ORM的更多相关文章
- 自己动手写ORM的感受
之前看到奋斗前辈和时不我待前辈的自己动手写ORM系列博客,感觉讲解的通俗易懂,清晰透彻.作为一个菜鸟,闲来也想着自己写一个ORM,一来加深自己对 ORM的理解,以求对EF,NHibernate等ROM ...
- (新)自己动手写ORM框架(1)-增删查改的使用
之前写过一个系列文章自己动手写ORM框架,经过在多个项目的中的使用,对这套代码进行了许多改进,下面是使用方法: 新增学员信息代码预览: DBHelper db = DBHelper.getInstan ...
- SQLAlchemy(1) -- Python的SQLAlchemy和ORM
Python的SQLAlchemy和ORM(object-relational mapping:对象关系映射) web编程中有一项常规任务就是创建一个有效的后台数据库.以前,程序员是通过写sql语句, ...
- 自己动手写Spring框架--IOC、MVC
对于一名Java开发人员,我相信没有人不知道 Spring 框架,而且也能够轻松就说出 Spring 的特性-- IOC.MVC.AOP.ORM(batis). 下面我想简单介绍一下我写的轻量级的 S ...
- 手写开源ORM框架介绍
手写开源ORM框架介绍 简介 前段时间利用空闲时间,参照mybatis的基本思路手写了一个ORM框架.一直没有时间去补充相应的文档,现在正好抽时间去整理下.通过思路历程和代码注释,一方面重温下知识,另 ...
- 动手写一个简单的Web框架(HelloWorld的实现)
动手写一个简单的Web框架(HelloWorld的实现) 关于python的wsgi问题可以看这篇博客 我就不具体阐述了,简单来说,wsgi标准需要我们提供一个可以被调用的python程序,可以实函数 ...
- 60行自己动手写LockSupport是什么体验?
60行自己动手写LockSupport是什么体验? 前言 在JDK当中给我们提供的各种并发工具当中,比如ReentrantLock等等工具的内部实现,经常会使用到一个工具,这个工具就是LockSupp ...
- 自己动手写ls命令——Java版
自己动手写ls命令--Java版 介绍 在前面的文章Linux命令系列之ls--原来最简单的ls这么复杂当中,我们仔细的介绍了关于ls命令的使用和输出结果,在本篇文章当中我们用Java代码自己实现ls ...
- 自己动手写线程池——向JDK线程池进发
自己动手写线程池--向JDK线程池进发 前言 在前面的文章自己动手写乞丐版线程池中,我们写了一个非常简单的线程池实现,这个只是一个非常简单的实现,在本篇文章当中我们将要实现一个和JDK内部实现的线程池 ...
随机推荐
- struts2是如何加载相关的package元素节点信息的
这不是一篇纯技术文章,而是一篇分享我个人在前后端分离路上收获的点点滴滴的文章,以此来为准备尝试前后端分离或者想了解前后端分离的童鞋做一个大体的讲解. 上一家公司是家小公司,做了一年的全栈开发,对前端的 ...
- 数据契约(DataContract)
原文地址:http://www.cnblogs.com/Gavinzhao/archive/2010/06/01/1748736.html 服务契约定义了远程访问对象和可供调用的方法,数据契约则是服务 ...
- 复星昆仲杨光:VR行业四大痛点
2016年,可是说是VR产业的爆发之年,从公司层面到资本层面都对VR产业给予了厚望,期望其能够在移动互联网之后带来革命性的突破,掀起新一轮技术主导的商业革命.而创业者们已经跃跃欲试,期望在资本的支持下 ...
- Android修改Eclipse 中的Default debug keystore路径,以及修改android的AVD默认路径
初学android,光是配置Eclipse就走了不少弯路,班里面有很多同学的计算 机名都是写的自己的中文姓名,结果导致了AVD文件默认保存在“C:\user\<username>\.and ...
- Mac下升级Nodejs
突然发现系统中的nodejs版本比较旧,想升级一下但又不想下载安装包一步一步安装, 发现还是可以很简单用命令行升级的. 首先得清理npm的缓存 sudo npm cache clean -f 安装 n ...
- Firebird数据库系统的开发团队
下载Firebird3的发布文档,上面列出了开发团队,仔细看了看,原来俄罗斯人是主导(内核开发),法国人.智利人.巴西人.日本人.荷兰人.捷克人都有.共17人,3人全职. able 13.1. Fir ...
- gridview汇出EXCEL (ExportGridViewToExcel(dt, HttpContext.Current.Response);)
调用 ExportGridViewToExcel(dt, HttpContext.Current.Response); private void ExportGridViewToExcel(DataT ...
- MongoDB与内存
来自 http://www.ttlsa.com/mongodb/mongodb-and-memory/# 但凡初次接触MongoDB的人,无不惊讶于它对内存的贪得无厌,至于个中缘由,我先讲讲Linu ...
- 微信公共平台开发-(.net实现)1--成为开发者
刚换了个新环境,哎这都快一个月了,还没适应过来,还是怀念老地方呀.老板让开发一个基于微信平台的开发项目,而且是用net实现.当时就蒙了,微信就用了一会个人赶脚不好,所以果断不用,现在让开发,而且查了一 ...
- EmberJs之数组绑定@each&[]
写在前面 好长时间没有写博客了,昨天花了些时间又整理了下之前发布过的<Ember.js之computed Property>文章,并创建了一个测试代码库,花了些时间,希望能使用测试代码的方 ...