综合编程

Python实现一个ORM模型类

微信扫一扫,分享到朋友圈

Python实现一个ORM模型类

ORM是三个单词首字母组合而成,包含了Object(对象-类),Relations(关系),Mapping(映射)。解释过字面意思,但ORM的概念仍然模糊。私以为要理解一个事物,最好的法子是搞明白它出现是为了解决什么问题。

一个简单的ORM模型

我们也可以通过元类来实现自己的ORM。下面将涉及两个知识点:元类,描述符。

首先完成属性描述符的设计:

class BaseFiled(object):
pass
class CharFiled(BaseFiled):
def __init__(self, max_len=10):
self.max_len = max_len
def __get__(self, instance, owner):
return self.value
def __set__(self, instance, value):
if isinstance(value, str):
# 判断类型进行控制
if len(value) <= self.max_len:
self.value = value
else:
raise TypeError('超出最大长度')
else:
raise TypeError('need a str')
def __delete__(self, instance):
self.value = None
class IntFiled(BaseFiled):
def __init__(self, max_len=10):
self.max_len = max_len
def __get__(self, instance, owner):
return self.value
def __set__(self, instance, value):
if isinstance(value, int):
# 判断类型进行控制
if len(str(value)) <= self.max_len:
self.value = value
else:
raise TypeError('超出最大长度')
else:
raise TypeError('need a int')
def __delete__(self, instance):
self.value = None
class BoolFiled(BaseFiled):
def __init__(self, max_len=10):
self.max_len = max_len
def __get__(self, instance, owner):
return self.value
def __set__(self, instance, value):
if isinstance(value, bool):
# 判断类型进行控制
self.value = value
else:
raise TypeError('need a bool')

实现一个元类:

class FieldMetaClass(type):
# 创建模型类的元类
def __new__(cls, name, bases, dic, *args, **kwargs):
if name == 'BaseModel':
return super().__new__(cls, name, bases, dic)
table_name = name.lower()
# 将类名转换成小写,对应数据表的名称
fields = {}
for k, v in dic.items():
# 判断value的类型是不是BaseFiled类型的 因为调用的类的父类就是BaseFiled 所以通过CharFiled等创建出来的对象也就是BaseFiled类型的
if isinstance(v, BaseFiled):
fields[k] = v
dic['t_name'] = table_name
dic['fields'] = fields
# 将类名和属性取出来放在一个字典中
return super().__new__(cls, name, bases, dic)

给模型类创建一个父类,具体原因及作用可以观察注释:

class BaseModel(metaclass=FieldMetaClass):
# 模型类的父类
def __init__(self, **kwargs):
# kwargs 传入的是一个字典
for k, v in kwargs.items():
setattr(self, k, v)
# setattr 设置属性  传入对象、属性名、属性值
def save(self):
# 保存一条数据,生成一条对应的sql语句
# 获取表名
t_name = self.t_name
# 获取字段名称
fields = self.fields
# 获取对应字段的值
filed_dict = {} # 创建一个字典用来存储键值对
for filed in fields.keys():
value = getattr(self, filed)
# 把遍历出来的键中的值找到
filed_dict[filed] = value
# 生成对应的sql语句
sql = 'INSERT INTO {0} VALUES {1};'.format(t_name, tuple(filed_dict.values()))

生成模型类:

class User(BaseModel):
# 用户模型类 在模型类中不会重写init方法,在它的父类中写init方法 它会自动继承
username = CharFiled()
pwd = CharFiled()
age = IntFiled()
live = BoolFiled()

调用方式:

a = User(username='12', pwd='19', age=20, live=True)
a.save()

这样就实现了一个模型类,注释写的个人感觉还是比较清晰的,有不清楚的欢迎留言交流

Predicting Electricity Outage with Keras and Python

上一篇

无法打开源文件QtWidgets/QApplication

下一篇

你也可能喜欢

评论已经被关闭。

插入图片

热门栏目

Python实现一个ORM模型类

长按储存图像,分享给朋友