手撸系列之——orm(对象关系映射)(代码片段)

penghengshan penghengshan     2022-12-11     770

关键词:

ORM:对象关系映射
类               》》》     数据库的一张表
对象             》》》     表的一条记录
对象点属性        》》》     记录某一个字段对应的值

废话不多少,先上代码:

# orm.py

from mysql_singletion import Mysql

# 设置表字段类,通常需要的属性为字段名,字段类型,是否为主键,默认值
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)

# 定义int类型字段类
class IntegerField(Field):
    def __init__(self, name, column_type="int", primary_key=False, default=0):
        super().__init__(name, column_type, primary_key, default)

# 自定义元类,用来拦截模型表的创建过程(也可使用__init__方法拦截)
class MyMetaClass(type):
    def __new__(cls, cls_name, cls_bases, cls_attrs):
        # models不是模型表,因此不需要拦截其产生过程,直接调用type类的__new__方法产生models类并返回结果
        if cls_name == "Models":
            return type.__new__(cls, cls_name, cls_bases, cls_attrs)

        # 拦截模型表的闯将过程,使其增加table_name,primary_key及mappings(字段信息)的属性
        table_name = cls_attrs.get("table_name",cls_name.lower())
        primary_key = None
        mappings = 

        #下面的for循环首先是将表的所有字段属性整合到mappings这个字典中,并确定主键字段
        for k,v in cls_attrs.items():
            # 取出表中所有由Field类产生的字段属性
            if isinstance(v,Field):
                mappings[k] = v
                if v.primary_key:
                    if primary_key:
                        raise TypeError("一张表只能有一个主键!")
                    primary_key = v.name
        # 由于已经将所有的字段属性添加到mappings中,需要将cls_attrs中的单个单个的字段属性删除
        for k in mappings.keys():
            cls_attrs.pop(k)
        # 检验表中最终是否有主键,如没有则报错,因为一个innodb引擎的mysql表有且只有一个主键
        if not primary_key:
            raise TypeError("一张表必须要有主键!")

        # 将下面三个属性添加至表的名称空间
        cls_attrs["table_name"] = table_name
        cls_attrs["primary_key"] = primary_key
        cls_attrs["mappings"] = mappings
        # 调用type类的__new__方法产生表那个类并返回
        return type.__new__(cls,cls_name,cls_bases,cls_attrs)


class Models(dict,metaclass=MyMetaClass):
    # __init__可以不写,最终也是直接调用dict类中的__init__方法去实例化,得到一个字典
    def __init__(self,**kwargs):
        super().__init__(**kwargs)

    # 由于继承字典类,对象无法直接点属性得到对应的属性值,__getatter__在对象点 不存在的属性 时触发,
    # 返回对象(也就是那个字典)属性(也就是字典中的key)对应的值,若字典中无该key则返回一个默认值。
    def __getattr__(self, item):
        return self.get(item,"没有该键!")

    # 使对象点属性设置或修改值的时候,能在对象(字典)中添加或修改其对应的key,value
    def __setattr__(self, key, value):
        self[key] = value

    # 类方法,表类调用进行数据的查操作
    @classmethod
    def select(cls, **kwargs):
        # 若每次查询都实例化一次Mysql的对象,那么当成千上万的用户访问服务器时压力太大,因此在此使用单例
        ms = Mysql.singletion()
        if not kwargs:
            sql = "select * from %s"%cls.table_name
            res = ms.select(sql)
        else:
            # 规定sql语句只能有一个查询条件,在此使用python代码对传入的参数进行限制,只取第一对参数进行查询
            k = list(kwargs.keys())[0]
            v = kwargs.get(k)
            # 这里的?就是一个纯粹的占位符,若一起使用%s则必须传值,因此先用?占位然后再用%s进行替换
            sql = "select * from %s where %s=?"%(cls.table_name,k)
            sql = sql.replace("?","%s")
            res = ms.select(sql,v)
        if res:
            # 下面这句代码可以说是orm的精髓,把查询出来的一条条记录再实例化成对象返回
            # res = [,,]
            # cls(name='...',password='...')
            return [cls(**r) for r in res]


if __name__ == '__main__':
    class Teacher(Models):
        table_name = "teacher"
        tid = IntegerField(name="tid",primary_key=True)
        tname = StringField(name="tname")
        age = IntegerField(name="age")


    t1 = Teacher(tid=1, tname="jason", age=18)
    print(t1.tid,t1.tname)
    print(Teacher.table_name)
    print(Teacher.primary_key)
    print(Teacher.mappings)
    print(Teacher.select(tname="李平老师"))
    
'''
    1  jason
    teacher
    id
    'id': <__main__.IntegerField object at 0x000001BBCF4DD630>, 'name':        <__main__.StringField object at 0x000001BBCF4DDA20>
    ['tid': 2, 'tname': '李平老师']
'''
# mysql_singletion.py

 pymysql


class Mysql(object):
    __instance = None

    def __init__(self):
        self.conn = pymysql.connect(
            host="127.0.0.1",
            port=3306,
            user="root",
            password="",
            database="day41",
            charset="utf8",
            autocommit=True,
        )
        self.cursor = self.conn.cursor(pymysql.cursors.DictCursor)

    def close_db(self):
        self.cursor.close()
        self.conn.close()

    # 查找功能,传入sql代码及相应的关键参数
    def select(self, sql, args=None):
        self.cursor.execute(sql, args)
        # 返回的结果是一个列表中包含一系列的字典,每一个字典对应数据库中的一条记录
        res = self.cursor.fetchall()
        return res

    # 插入及修改数据功能
    def execute(self, sql, args):
        try:
            self.cursor.execute(sql, args)
        except BaseException as e:
            print(e)

    # 单例,使外界调用时只需实例化一个对象即可
    @classmethod
    def singletion(cls):
        if not Mysql.__instance:
            cls.__instance = cls()
        return cls.__instance

需要留意的几点:

技术图片

技术图片

技术图片

技术图片

orm(关系对象映射)框架之面向对象(代码片段)

...函数公用同样参数时候,可以转变成类进行-分类 3.面向对象:数据和逻辑(属性和行为)组合在一起  函数编程:数据和逻辑分离 1特殊方法:2classFoo:3def__init__(self,name):4self.name=name567defshow(self):8print(self.name 查看详情

手撸orm

本文目录ORM简介Python中常用ORM框架 原生操作数据库模块pymysqlORM框架之SQLAlchemy手把手带你写一个自己的ORM框架回到目录ORM简介ORM即ObjectRelationalMapping,全称对象关系映射。当我们需要对数据库进行操作时,势必需要通过连接... 查看详情

django之orm(代码片段)

ObjectRelationalMapping(ORM)ORM介绍ORM概念对象关系映射(ObjectRelationalMapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将程序中... 查看详情

django之orm(代码片段)

 ORM概念对象关系映射(ObjectRelationalMapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关... 查看详情

java实现关系型数据库工具类jdbcutils系列五:orm对象关系映射(代码片段)

Java实现关系型数据库工具类JdbcUtils系列五:ORM对象关系映射一、ORM对象关系映射二、表结构和表对应的实体类三、查询mysql数据库元信息ORM映射到实体类中四、测试类五、完整代码六、运行测试类输出如下所示一、ORM对象关... 查看详情

django之orm(代码片段)

Django之ORM1.ORM介绍ORM概念对象关系映射(ObjectRelationalMapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将程序中的对象自... 查看详情

django之models和orm(代码片段)

ORMObjectRelationalMapping,简称ORM,是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。通过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系数据库中。优势:ORM解决的主要问题是对象和... 查看详情

django之orm(代码片段)

ORMORM即ObjectRelationalMapping(对象关系映射)对象关系映射(英语:(ObjectRelationalMapping,简称ORM,或O/RM,或O/Rmapping),是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换。从效果上说,它其实是创建... 查看详情

django之orm(代码片段)

目录ObjectRelationalMapping(ORM)ORM介绍ORM概念对象关系映射(ObjectRelationalMapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术.简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将程序中的对... 查看详情

orm对象关系映射之使用greendao进行crud操作(代码片段)

...以ORM程序设计技术应用而生,它主要是用于实现面向对象编程语言里不同类型系统的数据之间 查看详情

django之orm(代码片段)

...,QuerySet相关方法ObjectRelationalMapping(ORM)一,ORM介绍一,ORM概念对象关系映射(ObjectRelationalMapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。简单的说,ORM是通过使用描述对象和数据库之间映... 查看详情

harmonyos之数据管理·对象关系映射数据库的应用(代码片段)

...据库的SQL操作,针对实体和关系提供了增删改查等一系列的面向对象接口。应用开发者不必再去编写复杂的SQL语句,以操作对象的形式来操作数据库&#x 查看详情

django之orm操作(代码片段)

Django之ORM操作  ORM(ObjectRelationalMapping),对象关系模型,是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术.  优势:    提供了对数据库的映射关系,不用直接编写SQL,只需操作对象就能对数据库操作数据. ... 查看详情

orm对象关系映射(代码片段)

ORM(ObjectRelationalMapping):对象关系映射,通过创建一个类与数据库的表相对应,类的对象代指数据库中的一行数据。让用户不再写SQL语句,而是通过类以及对象的方式,和其内部提供的方法,进行数据库操作。功能:把用户输... 查看详情

手撸一个orm使用说明(代码片段)

传送门【手撸一个ORM】第一步、约定和实体描述【手撸一个ORM】第二步、封装实体描述和实体属性描述【手撸一个ORM】第三步、SQL语句构造器和SqlParameter封装【手撸一个ORM】第四步、Expression(表达式目录树)扩展【手撸一个ORM... 查看详情

44mysql&orm对象关系映射(代码片段)

orm模型  对象关系映射:ObjectRelationalMapping  是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换  ORM模型的简单性简化了数据库查询过程   三个核心原则:    简单性:以最基本的... 查看详情

django框架之模型(代码片段)

 ORM简介ORM,全拼Object-RelationMapping,中文意为对象-关系映射,是随着面向对象的软件开发方法发展而产生的。面向对象的开发方法是当今企业级应用开发环境中的主流开发方法,关系数据库是企业级应用环境中永久存放数据... 查看详情

django之模型(代码片段)

一、Model类  1.ORM思想  ORM:ObjectRelationshipMapping对象关系映射  通过操作对象方法,来进行关系型数据库操作  2.实现方式    在setting配置文件配置数据库    DATABASES=‘default‘:‘ENGINE‘:‘django.db.backends.mysql‘... 查看详情