电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

如何使用Python實現一個簡易的ORM模型

瀏覽:3日期:2022-06-19 18:44:35
目錄元類描述器

本文記錄下自己使用Python實現一個簡易的ORM模型

使用到的知識

1、元類

2、描述器

元類

對于元類,我的理解其實也便較淺,大概是這個意思

所有的類都是使用元類來進行創建的,而所有的類的父類中必然是object(針對Python3),Python中的元類只有一個(type),當然這里不包含自定義元類

下面我們來看下類的創建

class Test: # 定義一個類 passTest1 = type('Test2',(object,),{'name':'test'}) # 定義一個類print(type(Test))print(type(Test1))-----------------------<class ’type’><class ’type’>

從上面可以看出創建類,其實是有兩種方式,一種是通過class關鍵字來定義,一種是通過type來進行創建,當然常用的是使用class來進行創建了,在看最后的結果,可以看出類的類型為type。說明我們這個類就是由type來創建的

明白了這個之后我們再來梳理下怎么使用自定義元類來創建類,明白一點,自定義元類需要繼承type

class MetaClass(type): # 定義一個元類 passclass Test(metaclass=MetaClass): # 使用自定義元類來創建類 passprint(type(Test))--------------------------<class ’__main__.MetaClass’>

很明顯可以看出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 = valueelse: 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 = valueelse: 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_dictdic = {} # 定義一個空字典,用來裝屬性名和屬性值for k, v in fileds.items(): value = getattr(self, k) dic[k] = valuesql = '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 = valueelse: 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 = valueelse: 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_dictdic = {} # 定義一個空字典,用來裝屬性名和屬性值for k, v in fileds.items(): value = getattr(self, k) dic[k] = valuesql = '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模型的詳細內容,更多關于python 實現ORM模型的資料請關注好吧啦網其它相關文章!

標簽: Python 編程
相關文章:
主站蜘蛛池模板: 全自动烧卖机厂家_饺子机_烧麦机价格_小笼汤包机_宁波江北阜欣食品机械有限公司 | 深圳美安可自动化设备有限公司,喷码机,定制喷码机,二维码喷码机,深圳喷码机,纸箱喷码机,东莞喷码机 UV喷码机,日期喷码机,鸡蛋喷码机,管芯喷码机,管内壁喷码机,喷码机厂家 | 环讯传媒,永康网络公司,永康网站建设,永康小程序开发制作,永康网站制作,武义网页设计,金华地区网站SEO优化推广 - 永康市环讯电子商务有限公司 | 专业甜品培训学校_广东糖水培训_奶茶培训_特色小吃培训_广州烘趣甜品培训机构 | 世界箱包品牌十大排名,女包小众轻奢品牌推荐200元左右,男包十大奢侈品牌排行榜双肩,学生拉杆箱什么品牌好质量好 - Gouwu3.com | 济南轻型钢结构/济南铁艺护栏/济南铁艺大门-济南燕翔铁艺制品有限公司 | 焊锡丝|焊锡条|无铅锡条|无铅锡丝|无铅焊锡线|低温锡膏-深圳市川崎锡业科技有限公司 | 废旧物资回收公司_广州废旧设备回收_报废设备物资回收-益美工厂设备回收公司 | 管理会计网-PCMA初级管理会计,中级管理会计考试网站 | 废旧物资回收公司_广州废旧设备回收_报废设备物资回收-益美工厂设备回收公司 | 山东PE给水管厂家,山东双壁波纹管,山东钢带增强波纹管,山东PE穿线管,山东PE农田灌溉管,山东MPP电力保护套管-山东德诺塑业有限公司 | 阻燃剂-氢氧化镁-氢氧化铝-沥青阻燃剂-合肥皖燃新材料 | 广东机电安装工程_中央空调工程_东莞装饰装修-广东粤标建设有限公司 | BOE画框屏-触摸一体机-触控查询一体机-触摸屏一体机价格-厂家直销-触发电子 | 闸阀_截止阀_止回阀「生产厂家」-上海卡比阀门有限公司 | 气动球阀_衬氟蝶阀_调节阀_电动截止阀_上海沃托阀门有限公司 | 冷镦机-多工位冷镦机-高速冷镦机厂家-温州金诺机械设备制造有限公司 | 房在线-免费房产管理系统软件-二手房中介房屋房源管理系统软件 | 有源电力滤波装置-电力有源滤波器-低压穿排电流互感器|安科瑞 | 有机废气处理-rto焚烧炉-催化燃烧设备-VOC冷凝回收装置-三梯环境 | 施工电梯_齿条货梯_烟囱电梯_物料提升机-河南大诚机械制造有限公司 | 苏州工作服定做-工作服定制-工作服厂家网站-尺品服饰科技(苏州)有限公司 | 北京租车公司_汽车/客车/班车/大巴车租赁_商务会议/展会用车/旅游大巴出租_北京桐顺创业租车公司 | 全自动过滤器_反冲洗过滤器_自清洗过滤器_量子除垢环_量子环除垢_量子除垢 - 安士睿(北京)过滤设备有限公司 | 大学食堂装修设计_公司餐厅效果图_工厂食堂改造_迈普装饰 | 传动滚筒_厂家-淄博海恒机械制造厂 | 蒸压釜_蒸养釜_蒸压釜厂家-山东鑫泰鑫智能装备有限公司 | MES系统-WMS系统-MES定制开发-制造执行MES解决方案-罗浮云计算 | 钢格板|镀锌钢格板|热镀锌钢格板|格栅板|钢格板|钢格栅板|热浸锌钢格板|平台钢格板|镀锌钢格栅板|热镀锌钢格栅板|平台钢格栅板|不锈钢钢格栅板 - 专业钢格板厂家 | 杭州月嫂技术培训服务公司-催乳师培训中心报名费用-产后康复师培训机构-杭州优贝姆健康管理有限公司 | 专业深孔加工_东莞深孔钻加工_东莞深孔钻_东莞深孔加工_模具深孔钻加工厂-东莞市超耀实业有限公司 | 在线悬浮物浓度计-多参数水质在线检测仪-上海沃懋仪表科技有限公司 | 离子色谱自动进样器-青岛艾力析实验科技有限公司 | 活性炭-果壳木质煤质柱状粉状蜂窝活性炭厂家价格多少钱 | 电主轴,车床电磨头,变频制动电机-博山鸿达特种电机 | 查分易-成绩发送平台官网 | 双吸泵,双吸泵厂家,OS双吸泵-山东博二泵业有限公司 | 直线模组_滚珠丝杆滑台_模组滑台厂家_万里疆科技 | 招商帮-一站式网络营销服务|互联网整合营销|网络推广代运营|信息流推广|招商帮企业招商好帮手|搜索营销推广|短视视频营销推广 | 游泳池设备安装工程_恒温泳池设备_儿童游泳池设备厂家_游泳池水处理设备-东莞市君达泳池设备有限公司 | 手表腕表维修保养鉴定售后服务中心网点 - 名表维修保养 |