千家信息网

怎么用Python实现一个简易的ORM模型

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,这篇文章主要介绍"怎么用Python实现一个简易的ORM模型",在日常操作中,相信很多人在怎么用Python实现一个简易的ORM模型问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对
千家信息网最后更新 2026年11月01日怎么用Python实现一个简易的ORM模型

这篇文章主要介绍"怎么用Python实现一个简易的ORM模型",在日常操作中,相信很多人在怎么用Python实现一个简易的ORM模型问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"怎么用Python实现一个简易的ORM模型"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

元类

对于元类,我的理解其实也便较浅,大概是这个意思

所有的类都是使用元类来进行创建的,而所有的类的父类中必然是object(针对Python3),Python中的元类只有一个(type),当然这里不包含自定义元类

下面我们来看下类的创建

class Test:   # 定义一个类    passTest1 = type("Test2",(object,),{"name":"test"})  # 定义一个类print(type(Test))print(type(Test1))-----------------------

从上面可以看出创建类,其实是有两种方式,一种是通过class关键字来定义,一种是通过type来进行创建,当然常用的是使用class来进行创建了,在看最后的结果,可以看出类的类型为type。说明我们这个类就是由type来创建的

明白了这个之后我们再来梳理下怎么使用自定义元类来创建类,明白一点,自定义元类需要继承type

class MetaClass(type):  # 定义一个元类    passclass Test(metaclass=MetaClass):  # 使用自定义元类来创建类    passprint(type(Test))--------------------------

很明显可以看出Test类就是用MetaClass类创建出来的

描述器

从描述器的定义来说,只要一个类中实现了__get__、__set__、__delete__中的一个或几个,这个类的实例就可以叫描述器

下面我们来定义一个简易的描述器

class Describer:    def __set__(self, instance, value):        print("设置属性的时候会被调用")        self.value = value    def __get__(self, instance, owner):        print("获取属性的时候会被调用")        return self.value    def __delete__(self, instance):        print("删除属性的时候会被调用")        self.value = Noneclass Test:    name = Describer()t = Test()t.name = "xxxxx"print(t.name)----------------------设置属性的时候会被调用获取属性的时候会被调用xxxxx

从上面的代码中有没有什么想法?既然__set__方法会在我们设置属性的时候会被调用,那么我们是不是可以在设置属性前对这个属性做一些操作呢?

ORM模型

ORM模型到底是个啥?ORM对于后端研发来说肯定是不陌生的,包括很多后端框架现在都自带这个模型了

ORM(Object Relational Mapping)对象关系映射

既然是对象关系映射,那对象是啥?我的理解为:Python中的类与数据库之间的映射,对数据的操作就不用编写SQL语言了,因为都封装好了,比如你想插入一条数据,你就直接创建一个对象即可,

Python ------->>>> 数据库

类名 ------->>>> 数据库中的表名

对象 ------->>>> 数据库中的一行数据

属性 ------->>>> 数据库中的字段

大致就是上面的映射关系

ORM实现步骤

1、利用描述器实现对数据库字段的类型、长度限制

2、实现Mode类,也就是Python中的类

3、利用元类实现映射关系

好,我们先利用描述器来实现对数据字段的类型,长度限制

class BaseFiled:    passclass CharFiled(BaseFiled):    """定义一个字符串的类型限制"""    def __init__(self, length=10):        self.length = length    def __set__(self, instance, value):        if isinstance(value, str):            if len(value) <= self.length:                self.value = value            else:                raise ValueError("length can not exceed {}".format(self.length))        else:            raise TypeError("need a str")    def __get__(self, instance, owner):        return self.value    def __delete__(self, instance):        self.value = Noneclass IntFiled(BaseFiled):    """定义一个数值的类型限制"""    def __set__(self, instance, value):        if isinstance(value, int):            self.value = value        else:            raise TypeError("need a int")    def __get__(self, instance, owner):        return self.value    def __delete__(self, instance):        self.value = Noneclass BoolFiled(BaseFiled):    """定义一个布尔的类型限制"""    def __set__(self, instance, value):        if isinstance(value, bool):            self.value = value        else:            raise TypeError("need a bool")    def __get__(self, instance, owner):        return self.value    def __delete__(self, instance):        self.value = None

上面实现了三种,分别是字符串、数值、布尔值的,下面在来实现元类以及模型类

class MyMateClass(type):    """自定义一个元类"""    def __new__(cls, name: str, bases: tuple, dic: dict, *args, **kwargs):        """        :param name: name为模型类的类名也就是数据库中的表名        :param bases:  bases为一个元祖类型,里面装的是name这个类的父类        :param dic: dic为一个dict类型,装的是name这个类中的属性        :param args:        :param kwargs:        :return:        """        if name == "BaseMode":   # 判断类名是否为BaseMode,如果是则直接使用元类创建类,不做其他任何操作            return super().__new__(cls, name, bases, dic)        else:            table_name = name.lower()  # 将表名变成小写            filed_dic = {}   # 定义一个空的列表,用来装dic中属于BaseFiled类型的属性,因为dic中会有其他创建类时自动生成的属性,这些属性我们没必要去建立映射关系,所以需要将其剔除掉            for k, v in dic.items():                if isinstance(v, BaseFiled):                    filed_dic[k] = v            dic["t_name"] = table_name    # 将表名添加到dic中,实现类名与表名的映射关系            dic["filed_dict"] = filed_dic  # 将属于BaseFiled类型的属性给添加到dic中,实现属性与字段的映射关系            return super().__new__(cls, name, bases, dic)class BaseMode(metaclass=MyMateClass):    def __init__(self, **kwargs):        """        由于每一个模型类(也就是数据库表)的属性个数不一致,所以我们需要定义一个父类来进行定义初始化的属性        :param kwargs:        """        for k, v in kwargs.items():   # 遍历传进来的所有属性            setattr(self, k, v)   # 拿到这些属性后对self(也就是类本身)进行设置属性    def save(self):        """生成SQL语句"""        # 获取表名        table_name = self.t_name        # 获取所有的属性        fileds = self.filed_dict        dic = {}  # 定义一个空字典,用来装属性名和属性值        for k, v in fileds.items():            value = getattr(self, k)            dic[k] = value        sql = "insert into {} values{}".format(table_name, tuple(dic.values()))        return sqlclass User(BaseMode):    name = CharFiled()    age = IntFiled()    love = CharFiled(length=50)    live = BoolFiled()if __name__ == '__main__':    c = User(name="lc", age=12, love="hjh", live=True)    c.save()--------------------------insert into user values('lc', 12, 'hjh', True)

以上就实现了一个简单的ORM模型了,这个虽然在测试开发过程中用的很少(一般都是直接用框架中封装好的),学习这个也是为了更好的理解原理,后面好学习flask以及Django。

下面贴一下完整的代码吧

# -*- coding: utf-8 -*-# @Time    : 2021-05-11 10:14# @Author  : cainiao# @File    : Meat.py# @Software: PyCharm# @Content : 实现ORM模型class BaseFiled:    passclass CharFiled(BaseFiled):    """定义一个字符串的类型限制"""    def __init__(self, length=10):        self.length = length    def __set__(self, instance, value):        if isinstance(value, str):            if len(value) <= self.length:                self.value = value            else:                raise ValueError("length can not exceed {}".format(self.length))        else:            raise TypeError("need a str")    def __get__(self, instance, owner):        return self.value    def __delete__(self, instance):        self.value = Noneclass IntFiled(BaseFiled):    """定义一个数值的类型限制"""    def __set__(self, instance, value):        if isinstance(value, int):            self.value = value        else:            raise TypeError("need a int")    def __get__(self, instance, owner):        return self.value    def __delete__(self, instance):        self.value = Noneclass BoolFiled(BaseFiled):    """定义一个数值的类型限制"""    def __set__(self, instance, value):        if isinstance(value, bool):            self.value = value        else:            raise TypeError("need a bool")    def __get__(self, instance, owner):        return self.value    def __delete__(self, instance):        self.value = Noneclass MyMateClass(type):    """自定义一个元类"""    def __new__(cls, name: str, bases: tuple, dic: dict, *args, **kwargs):        """        :param name: name为模型类的类名也就是数据库中的表名        :param bases:  bases为一个元祖类型,里面装的是name这个类的父类        :param dic: dic为一个dict类型,装的是name这个类中的属性        :param args:        :param kwargs:        :return:        """        if name == "BaseMode":   # 判断类名是否为BaseMode,如果是则直接使用元类创建类,不做其他任何操作            return super().__new__(cls, name, bases, dic)        else:            table_name = name.lower()  # 将表名变成小写            filed_dic = {}   # 定义一个空的列表,用来装dic中属于BaseFiled类型的属性,因为dic中会有其他创建类时自动生成的属性,这些属性我们没必要去建立映射关系,所以需要将其剔除掉            for k, v in dic.items():                if isinstance(v, BaseFiled):                    filed_dic[k] = v            dic["t_name"] = table_name    # 将表名添加到dic中,实现类名与表名的映射关系            dic["filed_dict"] = filed_dic  # 将属于BaseFiled类型的属性给添加到dic中,实现属性与字段的映射关系            return super().__new__(cls, name, bases, dic)class BaseMode(metaclass=MyMateClass):    def __init__(self, **kwargs):        """        由于每一个模型类(也就是数据库表)的属性个数不一致,所以我们需要定义一个父类来进行定义初始化的属性        :param kwargs:        """        for k, v in kwargs.items():   # 遍历传进来的所有属性            setattr(self, k, v)   # 拿到这些属性后对self(也就是类本身)进行设置属性    def save(self):        """生成SQL语句"""        # 获取表名        table_name = self.t_name        # 获取所有的属性        fileds = self.filed_dict        dic = {}  # 定义一个空字典,用来装属性名和属性值        for k, v in fileds.items():            value = getattr(self, k)            dic[k] = value        sql = "insert into {} values{}".format(table_name, tuple(dic.values()))        return sqlclass User(BaseMode):    name = CharFiled()    age = IntFiled()    love = CharFiled(length=50)    live = BoolFiled()if __name__ == '__main__':    c = User(name="lc", age=12, love="hjh", live=True)    print(c.save())    # c.name="lc"    # print(c.name)

到此,关于"怎么用Python实现一个简易的ORM模型"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

属性 类型 模型 数据 数据库 限制 也就是 类名 时候 学习 简易 字段 对象 数值 生成 字符 字符串 一致 必要 个数 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网加科技 河南云网互联网络科技有限公司 金诺互联网科技 科技互联网技术 互联网科技的发展 致聘互联网科技 腾讯科技 互联网女皇 美国互联网黑科技 栖莱科技互联网股份有限公司 浙江互联网科技研学营 坤平互联网科技 银川新华互联网科技学校联系电话 浙南科技城互联网大厦建设工程 迪庆互联网科技招生 保险科技服务互联网营销体系 为客找房互联网科技公司怎么样 南通创西澳互联网科技有限公司 中国新注册互联网科技 亚光科技低轨卫星互联网 银川新华互联网科技学校招聘 朗涯互联网科技 上海致骋互联网科技 火传媒上海互联网科技 互联网科技公司名称 成都玖崟互联网科技有限公司乐商圈怎么样 湖南诚度互联网科技有限公司 互联网公司科技股 南平创想时代互联网科技有限公司 互联网科技研发水平 美国五大互联网科技公司市值多少
0