Home

Y's Blog

Salted fish without dreams

Home Notes About Github

2018-11-19
简易ORM的编写

利用Python中的元类编写的简易版的ORM(Object Relational Mapping,对象关系框架)

此代码是跟着传智播客中的dongge写的,跟着视频学习也算对元类有了一个基本的理解

也可以参见此篇博客 https://segmentfault.com/a/1190000011447445

道生一,一生二,二生三,三生万物 开始揭开元类的面纱

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78

#-*- coding:utf-8 -*-
__author__ = 'lenovo'

class ModelMetalclass(type):
# name,bases,attrs可以这样理解
# name:我是谁,类的名字
# bases:我从哪里来,继承的父类
# attrs:我到哪里去,类自己本身包含的属性
def __new__(cls, name, bases, attrs):
mappings = dict()

#判断是否需要保存
for k,v in attrs.items():
# 判断是否是指定的StringField或InterField的实例对象
if isinstance(v, tuple):
mappings[k] = v

# 由于attrs中的key和value已经存储在mappings中了
# 所以删除一些重复的属性
for k in mappings.keys():
attrs.pop(k)

# uid/name/email/password存储
# 保存属性和列的映射关系
attrs['__mappings__'] = mappings
# 假设表名与类名一致
attrs['__table__'] = name

# 返回创建的类对象
return type.__new__(cls,name,bases,attrs)


class User(metaclass=ModelMetalclass):
uid = ('uid',"int unsigned")
name = ('username',"varchar(30")
email = ('email' , "varchar(30)")
password = ('password',"varchar(30)")
# 当指定元类之后,以上的属性将不再类中,而是在__mappings__属性指定的字典当中存储
# 以上User类中有:
# __mappings__={
# 'uid' : ('uid',"int unsigned"),
# 'name' : ('username',"varchar(30"),
# 'email' : ('email' , "varchar(30)"),
# 'password' : ('password',"varchar(30)")
# }
# __table__ ="User"

def __init__(self,**kwargs):
for name,value in kwargs.items():
#setattr(object, name, values)
# 给对象的属性赋值,若属性不存在,先创建再赋值。
setattr(self,name,value)

def save(self):
fields = []
args = []
for k,v in self.__mappings__.items():
fields.append(v[0])
#getattr() 函数用于返回一个对象属性值。
# 这时的属性值是调用User类时传入的
args.append(getattr(self,k,None))

args_temp = list()
for temp in args:
# 判断是否是数字类型,是数字类型时拼接字符串不用加''
if isinstance(temp,int):
args_temp.append(str(temp))
elif isinstance(temp,str):
args_temp.append("""'%s'"""%temp)

sql = 'inser into %s (%s) values (%s);'%(self.__table__,','.join(fields),','.join(args_temp))

print('SQL:%s'%sql)

user =User(uid=12345,name='LS',email='xxx@qq.com',password='pwd')
#print(user.__dict__)
user.save()

Y's Blog

scribble

Home Notes About Github