编写ORM-解析

个人笔记:仅做学习记录    ORM-用来建立数据库和python的中间件,是任务逻辑层和数据库层的桥梁,就是用来简化对数据库进行的增删改查操作,将每一个表实例化为一个对象,每个这个对象中都有自己定义的增删改查的方法和各种属性,对这个表结构性操作的时候就只需要调用不同的操作方法就好了,不同的表就是不同的实例化对象。简化了数据库的学习,不需要创建数据库,不需要编写数据库访问层代码,执行数据库操作就是...
摘要由CSDN通过智能技术生成

个人笔记:仅做学习记录

    ORM-用来建立数据库和python的中间件,是任务逻辑层和数据库层的桥梁,就是用来简化对数据库进行的增删改查操作,将每一个表实例化为一个对象,每个这个对象中都有自己定义的增删改查的方法和各种属性,对这个表结构性操作的时候就只需要调用不同的操作方法就好了,不同的表就是不同的实例化对象。简化了数据库的学习,不需要创建数据库,不需要编写数据库访问层代码,执行数据库操作就是调用不同表的不同方法。具体解释见前一个博客。

    我需要实现的是可以实现如下代码:

    from orm import Model,StringField,IntegerField

    class User(Model):

        __table__ ='user'

        id = InterField(primary_key = True)  #类INtegerField的实例化对象

        name = StringField()

就是可以创建数据库的表对应类,这个类继承自Model基类,这个基类创建的过程又是根据metaclass=ModelMetaclass这个元类来创建的,每一个Model的子类也继承了这个元类,也就是在子类创建的时候,也会自动去调用metaclass这个属性,来修改这个子类的创建。上面orm模块就是自己定义的。所以我们需要做的就是:

创建元类ModelMetaclass:元类是所有后面的元类,比如Model,比如后面继承Model的子类,元类中包含所有设计到数据库操作的方法、属性。

再创建基类Model:Model继承自dict类,也就是所有数据库数据都是类似dict对象,所以需要继承这个类,然后又可以根据元类来对dict类中的相关属性、方法修改。

创建StringField,IntegerField类:指的后面表中(类中)不同属性的类型,比如整数类型,字符串类型。相当于之前建立一个整数型的id属性,每一个这个创建出的整数实际上就是int类的一个实例化对象(python中任何东西都是对象,包括元类也是自身的对象),我们这里就是需要自己定义int这个类。


数据库连接池

    由于大量的数据库的连接和关闭会导致资源损耗,如果可以在查询数据库之后 ,不关闭数据库连接,当别人使用时,把这个连接给别人用,就避免了一次建立数据库的连接。数据库连接池的基本思想是为数据库连接建立一个“缓冲池”。预先在缓冲池中建立一定数量的连接,当需要建立数据库连接时 ,只需要从缓冲池中取出一个,使用完毕后放回去,我们可以通过设定连接池最大连接数来防止系统无尽的与数据库连接(这里是网上搜索的关于连接池的解释)。但是这里的连接池并没有建立大量连接,好像是只要一个数据库连接?

传入参数pool和**kw,**kw指的接收不限个数个关键字参数,以dict形式存储参数,这里连接池创建函数传入的是host,port,user等连接的数据库信息,存入dict类型的kw变量中,再赋值给__pool全局变量。loop表示当前创建的事件循环。调用aiomysql.create_pool函数即可以连接到指定数据库上。返回给全局变量__pool存储连接池。这里就是只是打开一个连接,传入合适参数,后面其他地方需要打开数据库连接的时候,只用传入__pool全局变量即可,__pool就是一个已经打开的数据库连接,不需要每次都传入数据库参数,减少重复工作。


def log(sql,args=()):

    logging.info('SQL: %s' %sql)

定义log函数,传入的应该是数据库语句,这个函数在每个具体的数据库操作函数的开头调用,用来打印当前执行的sql语句。


select函数:数据库查询select函数,传入的参数是 sql语句,args参数是后面sql语句中占位符的参数列表,size是返回的结果行数。

 #获取数据库连接
    async with __pool.acquire() as conn:
        #获取游标,默认游标返回的结果为元组(每一项是另一个元组),这里可以通过aiomysql.DictCursor指定元组的元素为字典
        async with conn.cursor(aiomysql.DictCursor) as cur:
            #调用游标的execute()方法来执行sql语句,execute()接收两个参数,第一个为sql语句(可以包含占位符),第二个为占位符            #对应的值(也就是参数列表中传入的args),使用该形式可以避免直接使用字符串拼接出来的sql的注入攻击
            #sql语句的占位符为?,mysql里为%s,做替换
            await cur.execute(sql.replace('?', '%s'), args or ())
            #size有值就获取对应数量的数据
            if size:
                rs = await cur.fetchmany(size)
            else:
                #获取所有数据库中的所有数据,此处返回的是一个数组,数组元素为字典
                rs = await cur.fetchall()
        logging.info('rows returned: %s' % len(rs))
        #logging.info(rs)
        return rs

SQL注入攻击:要坚持使用带参数的SQL,为了防止SQL注入攻击,SQL注入即是指web应用程序

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值