• python自定义ORM并操作数据库


    看这个代码之前先去看上篇文章,理解type的用法及元类的含义:

    ORM可以代替pymysql,实现将python语义装换为sql语句,简单化

        import pymysql
        '''
        metaclass,直译为元类,简单的解释就是:
        
        当我们定义了类以后,就可以根据这个类创建出实例,所以:先定义类,然后创建实例。
        
        但是如果我们想创建出类呢?那就必须根据metaclass创建出类,所以:先定义metaclass,然后创建类。
        
        连接起来就是:先定义metaclass,就可以创建类,最后创建实例。
        
        所以,metaclass允许你创建类或者修改类。换句话说,你可以把类看成是metaclass创建出来的“实例”。
        
        当我们传入关键字参数metaclass时,魔术就生效了,它指示Python解释器在创建Student时,
        
        要通过ModelMetaClass.__new__()来创建,在此,我们可以修改类的定义,比如,加上新的方法,然后,返回修改后的定义。
        '''
        class Field(object):#定义一个字段类
            def __init__(self,name,column_type):
                self.name = name#字段名
                self.column_type = column_type#字段类型
            def __str__(self):
                return "<%s:%s>"%(self.name,self.column_type)
        
        class StringField(Field):#字符串类型字段,继承Field
            def __init__(self,name):
                super(StringField,self).__init__(name,"varchar(100)")
                # super(StringField, self).__init__(name,char(20))
        
        class IntegerField(Field):#数字类型字段,继承Field
            def __init__(self,name):
                super(IntegerField,self).__init__(name,"int")
        
        class ModelMetaClass(type):#定义一个元类
            def __new__(cls, name,bases,attrs):
                '''
                :param name: 类的名称
                :param bases: 类的继承
                :param attrs:  类的属性
                :return:
                '''
                if name == "Model":#如果传入的name:类名为Model则不进行操作,直接返回type类的相关参数
                    return type.__new__(cls,name,bases,attrs)
                    # return super(ModelMetaClass, self).__new__(cls,name,bases,attrs)
                print('Found model: %s' % name)  # 打印当前实例的类名称
                mapping = dict() #空字典
                for k,v in attrs.items(): #遍历属性
                    print('key:%s,value:%s' % (k, v))#打印遍历attrs的key和value
                    if isinstance(v,Field): #判断属性是否Field的实例
                        mapping[k] = v #添加到mapping当中
                # print(mapping)
                for k in mapping.keys(): #返回所有键
                    attrs.pop(k) #mapping里存在的内容从属性当中删除
                attrs["__mapping__"] = mapping  #设定__mapping__属性来保存字段
                attrs["__table__"] = name #设定类名和表名一致(不区分大小写)
                # print(attrs)
                return type.__new__(cls,name,bases,attrs)#返回给类实例,这里为Student
        
        class Model(dict,metaclass = ModelMetaClass):#创建一个实例类,设置其元类
            def __init__(self,**kwargs):
                self.db = pymysql.connect(#链接数据库
                    host = "localhost",
                    user = "root",
                    password = "123",
                    database = "test"
                )
                self.cursor = self.db.cursor()
                super(Model,self).__init__(**kwargs)
        
            def __getattr__(self, key):
                return self[key]#返回对象的属性值
                # print(self[key])
            def __setattr__(self, key, value):
                self[key] = value#设置对象的属性及其对应的值
        
        
            def save(self):
                fields = [] #空列表用来存储字段
                args = [] #空列表用来存储字段的值
                for k,v in self.__mapping__.items():
                    fields.append(v.name)#此时,v为field子类的实例,因此可以取出类属性name,作为字段名
                    # print(getattr(self, k, None))
                    args.append(getattr(self,k,None))#此时调用了self,则将传入的参数调用,此时再取变量的值,则为传入的实参
                sql = "insert into %s(%s) values (%s)"%(
                    self.__table__,
                    ",".join(fields),
                    ",".join([repr(str(i)) for i in args]
                       )) #sql拼接
                self.cursor.execute(sql)
                print(sql)
            def __del__(self):
                '''
                回收内存
                '''
                self.db.commit()
                self.cursor.close()
                self.db.close()
        
        class Student(Model):#model实例类的子类
            name = StringField("name")
            # print(name)
            room_id = IntegerField("room_id")
            # print(room_id)
        
        u = Student(name = "张3",room_id = 6)#实质是创建了一个字典的对象
        u.save()#调用父类的save方法
    
  • 相关阅读:
    5.对象的简化属性
    7.函数参数默认值
    python中argparse
    VC 6.0 打开文件出错
    【UNIX程序设计教程】 阅读初体验(1)
    引以为鉴ARM开发板连线注意事项
    windows xp宿主机 + Linux 虚拟机 网络配置
    Gcc编译选项分析
    ADS下调试出现的警告信息
    S3C2440串口通讯实现
  • 原文地址:https://www.cnblogs.com/ilovepython/p/11068848.html
Copyright © 2020-2023  润新知