欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

python ORM

程序员文章站 2022-04-19 07:57:57
...

1)为什么要用ORM

常规情况我们通过pymysql进行mysql数据库的操作,但是这个操作有一定的局限。
1、使用pymysql必须要返回mysql
2、使用原生的sql语句嵌套的python脚本当中,本身就不合适。
所以有了ORM(数据库映射关系),将python的数据类型和对象转换为mysql的数据类型和对象。可以通过python语句操作mysql。

2)工作原理

1、ORM借助元类进行创建
2、python可以动态创建类,创建类的类就是元类。
3、type除了返回类型还可以返回类对象,就是创建类对象

3)type元类介绍

type是一种特殊的元类
1、type只传入一个参数,返回参数的类型(即常用的检测对象类型)
2、type传入三个参数,创建类对象

t = type('hello', (), {'a':1})
print(t)
T = t()
print(T.a)

第一个参数是 类名称,要用字符串
第二个参数是 继承对象,要用元组,单元素元组要加,
第三个参数是 属性,以字典的格式,键属性名 值属性值

4)ORM框架

import pymysql

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):
    def __init__(self,name):
        super().__init__(name,'varchar(100)')

class IntegerField(Field):
    def __init__(self,name):
        super(IntegerField, self).__init__(name,'int')

class ModelMetaClass(type):
    def __new__(cls, name, bases, attrs):
        if name == 'Model':
            return type.__new__(cls, name, bases, attrs)
        mapping = dict()
        #k是字符串,v是地址
        for k,v in attrs.items():
            if isinstance(v, Field):
                mapping[k] = v
        for k in mapping.keys():
            attrs.pop(k)
        attrs['__mapping__'] = mapping
        attrs['__table__'] = name
        return type.__new__(cls, name, bases, attrs)

class Model(dict, metaclass=ModelMetaClass):
    def __init__(self, **kwargs):
    	#连接数据库创建游标
        self.db = pymysql.connect(
            host='地址',
            user='用户名',
            password='密码',
            database='要连接的数据库'
        )
        self.cursor = self.db.cursor()
        super(Model, self).__init__(**kwargs)

    def __getattr__(self, key):
        # print(self)
        return self[key]

    def __setattr__(self, key, value):
        self[key] = value

    def save(self):
        fields = []
        args = []
        for k,v in self.__mapping__.items():
            # print(k,v)
            fields.append(v.name)
            # print(2,fields)
            args.append(getattr(self, k, None))
            print(1,args)
            #sql语句的创建时执行
            sql = 'insert into %s(%s) value(%s)'%(
                self.__table__,
                ','.join(fields),
                ','.join([repr(str(i)) for i in args])
            )
        self.cursor.execute(sql)
        # print(sql)


    def __del__(self):
    	#在内存回收之前提交操作并关闭数据库连接
        self.db.commit()
        self.cursor.close()
        self.db.close()

class stu1(Model):
    id = IntegerField('id')
    name = StringField('name')
    age = IntegerField('age')

u = stu1(id = 2, name = "老边",age = 18)
u.save()

5)学习ORM的建议

1、了解type的用法
2、善于利用debug;一定要动手练几遍,在不懂的地方写几个print看什么时候会输出,了解其执行顺序
3、不能只看,看不懂就不练,要多练,练中学,学中练

相关标签: ORM