Python 实现简易版ORM

本文介绍了ORM(对象关系映射)的基本概念,它简化了数据库查询过程,通过对象的点语法操作数据,避免直接使用SQL。然后,文章详细阐述如何实现一个简单的Python ORM,包括利用字典存储数据、重写`__getattr__`和`__setattr__`方法,以及使用元类和pymysql库进行数据库操作。最后,展示了如何通过这个ORM进行数据库的增删查改操作。
摘要由CSDN通过智能技术生成

ORM:对象关系映射

用来把对象模型表示的对象映射到基于S Q L 的关系模型数据库结构中去。这样,我们在具体的操作实体对象的时候,就不需要再去和复杂的 SQL 语句打交道,只需简单的操作实体对象的属性和方法 。ORM 技术是在对象和关系之间提供了一条桥梁,前台的对象型数据和数据库中的关系型的数据通过这个桥梁来相互转化 。

ORM模型的简单性简化了数据库查询过程。使用ORM查询工具,用户可以访问期望数据,而不必理解数据库的底层结构。

实现简易版ORM

因为数据库的一张表相当于创建一个类,表内的一条记录相当一个对象,那我们就要实现利用对象的点语法可以取出表内的数据。

这里利用字典k-v键值对的形式存储数据的特点实现对象的点语法取值

首先创建一个类,继承dict类,重写 __ getattr __ ,__ setattr __ 方法实现对象的点语法取值和存值。

class Models(dict):
    def __init__(self,**kwargs):
        super().__init__(**kwargs)

    # __getattr__: 在对象获取它没有的属性和方法的时候自动触发
    def __getattr__(self, item):
        return self.get(item,'该key不存在!')

    # __setattr__: 在对象点属性设置属性值的时候自动触发
    def __setattr__(self, key, value):
        self[key] = value
        
res = Models(name='linwow',password=123)
print(res.id)
res['password'] = 456
print('用对象的形式赋值:',res.name)
print('用字典的形式赋值:',res.password)
'''
该key不存在!
用对象的形式赋值: linwow
用字典的形式赋值: 456
'''    

表中包含字段名和属性,这里利用类的方式实现 varchar 和 int 两种类型的字段

表的字段通常需要有的属性字段名,字段类型,是否是主键,默认值
class Field(object):
    def __init__(self,name,column_type,primary_key,default):
        self.name = name
        self.column_type = column_type
        self.primary_key = primary_key
        self.default = default

定义一个类,可以实例化varchar类型的字段
class Stringfield(Field):
    def __init__(self,name,column_type = 'varchar(32)',primary_key = False,default=None):
        super().__init__(name,column_type,primary_key,default)

定义一个类,可以实例化varchar类型的字段
class IntegerField(Field):
    def __init__(self,name,column_type='int',primary_key=False,default=0):
        super().__init__(name,column_type,primary_key,default)

在创建表的时候我们需要对一些字段和属性进行规范,所以利用元类来控制对象的创建。

class MyMetaClass(type):
    # 元类被继承是传入的参数为(’类名‘,’类的基类‘,’类的名称空间‘,所以直接用三个形参来接受
    def __new__(cls, class_name,class_bases,class_attrs):
        # 因为元类是用来拦截模型表的创建过程,而models并不是一张模型表,所以不需要它的创建过程
        if class_name =='Models':
            return type.__new__(cls,class_name,class_bases,class_attrs)
        table_name = class_attrs.get('table_name',class_name)
        primary_key = None
        # 用来存储自己定义的字段类型的属性
        mappings = {
   }
        # 下面的for循环需要做两件事
        # 1.将单个单个的字段整合成一个
        # 2.确定当前表当地哪个字段是主键
        for k,v in class_attrs.items():
            # 拿出所有自己定义的表的字段属性
            if isinstance(v,Field):
                # 将所有的自己定义的表的字段存入字典中
                mappings[k] = v
                # 校验一张表不能有多个主键
                if v.primary_key:
                    raise TypeError('一张表只能有一个主键')
                primary_key = v.name
        # 循环mapping拿到所有的自定义字段名
        for k 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值