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

参考:使用元类

Python - 动手写个ORM的更多相关文章

  1. 自己动手写ORM的感受

    之前看到奋斗前辈和时不我待前辈的自己动手写ORM系列博客,感觉讲解的通俗易懂,清晰透彻.作为一个菜鸟,闲来也想着自己写一个ORM,一来加深自己对 ORM的理解,以求对EF,NHibernate等ROM ...

  2. (新)自己动手写ORM框架(1)-增删查改的使用

    之前写过一个系列文章自己动手写ORM框架,经过在多个项目的中的使用,对这套代码进行了许多改进,下面是使用方法: 新增学员信息代码预览: DBHelper db = DBHelper.getInstan ...

  3. SQLAlchemy(1) -- Python的SQLAlchemy和ORM

    Python的SQLAlchemy和ORM(object-relational mapping:对象关系映射) web编程中有一项常规任务就是创建一个有效的后台数据库.以前,程序员是通过写sql语句, ...

  4. 自己动手写Spring框架--IOC、MVC

    对于一名Java开发人员,我相信没有人不知道 Spring 框架,而且也能够轻松就说出 Spring 的特性-- IOC.MVC.AOP.ORM(batis). 下面我想简单介绍一下我写的轻量级的 S ...

  5. 手写开源ORM框架介绍

    手写开源ORM框架介绍 简介 前段时间利用空闲时间,参照mybatis的基本思路手写了一个ORM框架.一直没有时间去补充相应的文档,现在正好抽时间去整理下.通过思路历程和代码注释,一方面重温下知识,另 ...

  6. 动手写一个简单的Web框架(HelloWorld的实现)

    动手写一个简单的Web框架(HelloWorld的实现) 关于python的wsgi问题可以看这篇博客 我就不具体阐述了,简单来说,wsgi标准需要我们提供一个可以被调用的python程序,可以实函数 ...

  7. 60行自己动手写LockSupport是什么体验?

    60行自己动手写LockSupport是什么体验? 前言 在JDK当中给我们提供的各种并发工具当中,比如ReentrantLock等等工具的内部实现,经常会使用到一个工具,这个工具就是LockSupp ...

  8. 自己动手写ls命令——Java版

    自己动手写ls命令--Java版 介绍 在前面的文章Linux命令系列之ls--原来最简单的ls这么复杂当中,我们仔细的介绍了关于ls命令的使用和输出结果,在本篇文章当中我们用Java代码自己实现ls ...

  9. 自己动手写线程池——向JDK线程池进发

    自己动手写线程池--向JDK线程池进发 前言 在前面的文章自己动手写乞丐版线程池中,我们写了一个非常简单的线程池实现,这个只是一个非常简单的实现,在本篇文章当中我们将要实现一个和JDK内部实现的线程池 ...

随机推荐

  1. 图片浏览(CATransition)转场动画

    Main.storyboard ViewController.m // //  ViewController.m //  8A04.图片浏览(转场动画) // //  Created by huan ...

  2. [Linux] xargs

    xargs 命令可以将一个命令的输出,作为另一个命令的输入! 这里听来好像是管道的功能,之所以有xargs是因为有的命令不知吃管道,这时xargs就派上用场了! 具体的方法是:前一个命令的输出会使用空 ...

  3. Unity中使用多构造函数(转)

    如果要实例化的类只有一个构造函数, 则使用方法很简单使用方法如下: 1 2 3 4 5 6 7 using (IUnityContainer container = new UnityContaine ...

  4. 《Linux内核分析》之第四章读书笔记

    4.1多任务 多任务操作系统:同时并发地交互执行多个进程的操作系统 多任务操作系统会使多个进程处于堵塞或者睡眠状态.这些任务尽管位于内存,但是并不处于可运行状态.这些进程利用内核堵塞自己,直到某一事件 ...

  5. Python学习之路--Socket

    Socket socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求. sock ...

  6. 关于gridview里加按钮事件的总结

    1. onrowcommand="GridView1_RowCommand1" 在gridview申明时的属性里要有,然后找到闪电,双击 还有要把那个按钮行模板化,就是箭头里面的t ...

  7. UITextField 的重写

    在很多产品设计的时候,产品设计人员设计出来的输入框总会要求,文字的内容距离做边框多少像素,编辑区域的其实点,距离左边多少像素,很多人绝的难以适应!其实这些都不存在很大的技术难度,一下这些方式都可以达到 ...

  8. hdu 3951 - Coin Game(找规律)

    这道题是有规律的博弈题目,,, 所以我们只需要找出规律来就ok了 牛人用sg函数暴力找规律,菜鸟手工模拟以求规律...[牢骚] if(m>=2) { if(n<=m) {first第一口就 ...

  9. 《利用Python进行数据分析》第7章学习笔记

    数据规整化:清理.转换.合并.重塑 合并数据集 pandas.merge pandas.concat combine_first 数据库风格的DataFrame合并 索引上的合并 join()实例方法 ...

  10. Java中创建对象的几种方式

    Java中创建对象的五种方式: 作为java开发者,我们每天创建很多对象,但是我们通常使用依赖注入的方式管理系统,比如:Spring去创建对象,然而这里有很多创建对象的方法:使用New关键字.使用Cl ...