自定义ORM框架

ORM: Object Relational Mapping---对象关系映射

类名---表名, 一个对象的某个属性值---某个记录, 一个对象的属性值---一条记录, 对象.属性---字段

  • 存储对象 --> dict --> Json --> Mysql
  • Mysql --> Jason --> dict --> 获取对象
  1. 一个对象中的所有属性名和属性值映射成一个字典中的keys和values
  2. 将映射字典序列化成json格式
  3. 将json格式数据编码传输到服务器
  4. 在服务器将二进制数据解码并反序列化存入mysql数据库中

自定义元类

'''
自定义元类:
    继承type类, 重写__new__方法, 控制类在创建时自动对类的名称空间中的属性进行相应的操作, 包括:
        1. 一个表类的名称空间中必须要有一个表名的属性---模型表类除外
        2. 一个表类的名称空间中的所有字段属性中, 必须有且仅有一个字段的主键为True
        3. 将一个表类的名称空间中的所有字段属性放入一个独立字典中, 与名称空间中的其他属性区分开, 
           从而方便获取字段属性的属性名, 因其与字段对象中的字段名同名, 故等价于方便了字段名的获取
'''


# 自定义元类
class OrmMeta(type):
    # 参数"mcs"为自定义的元类, 由"msc"来创建一个空类
    def __new__(mcs, cls_name, cls_bases, cls_dic):

        # 过滤掉"TableModel"类, 将其正常创建
        if cls_name == 'TableModel':
            return type.__new__(mcs, cls_name, cls_bases, cls_dic)

        # 保证一个表必定有一个表名
        table_name = cls_dic.get('table_name')
        if not table_name:
            cls_dic['table_name'] = cls_name

        # 定义一个字典存储一个表类中的所有字段对象
        field_obj_dic = {}

        # 保证有且仅有一个主键
        count = 0
        for key, value in cls_dic.items():  # 遍历表类的名称空间
            if isinstance(value, FieldBase):  # 过滤掉非字段对象的数据
                field_obj_dic[key] = value  # 添加字段对象至字典
                if value.primary_key:  # 判断主键是否存在
                    primary_key_name = key  # 记录主键的字段名
                    count += 1  # 对主键总数计数

        if count > 1:
            raise TypeError('只能有一个主键值!')  # 主键个数大于1报错
        if count == 0:
            key = list(field_obj_dic)[0]
            primary_key_name = field_obj_dic.get(key).field_name  # 没有主键默认将第一个字段名设为主键

        # 剔除类的名称空间中的字段对象数据, 节省内存空间
        for key in field_obj_dic.keys():
            cls_dic.pop(key)

        # 给类的名称空间添加主键
        cls_dic['primary_key_name'] = primary_key_name

        # 给类的名称空间添加包含一个表中的所有字段对象的字典
        cls_dic['field_obj_dic'] = field_obj_dic

        return type.__new__(mcs, cls_name, cls_bases, cls_dic)

定义表模型类

# 定义表模型类
class TableModel(dict, metaclass=OrmMeta):
    # 通过"对象.属性名 = 属性值"的方式往字典对象中存储数据
    def __setattr__(self, key, value):
        self[key] = value

    # 通过"对象.属性名"的方式从字典对象中获取数据
    def __getattr__(self, item):
        return self.get(item)


# 创建用户表类, 每个字段属性组合对应的字段对象
class UserTable(TableModel):
    # 表名
    table_name = 'user_info'

    # 每个字段属性
    user_id = IntegerField('user_id', primary_key=True)
    user_name = StringField('user_name')
    user_pwd = StringField('user_pwd')


# 创建电影表类
class MovieTable(TableModel):
    movie_id = IntegerField('movie_id', primary_key=True)
    movie_name = StringField('movie_name')
    movie_pwd = StringField('movie_pwd')


user1 = UserTable(user_id=1, user_name='tank', user_pwd='123')
print(UserTable.__dict__)
原文地址:https://www.cnblogs.com/-406454833/p/11807176.html