zoukankan      html  css  js  c++  java
  • python自学笔记之开源小工具:SanicDB介绍

    SanicDB 是为 Python的异步 Web 框架 Sanic 方便操作MySQL而开发的工具,是对 aiomysql.Pool 的轻量级封装。Sanic 是异步IO的Web框架,同时用异步IO读写MySQL才能更大发挥它的效率。虽然这个模块叫做 SanicDB,但是它可以用在任何异步IO操作MySQL的地方。

    SanicDB的灵感来源于tornado里面的对MySQLdb(MySQL的C语言接口的Python封装)的操作,后来tornado把它去除了,就有人把这部分代码写成一个单独的模块叫做 torndb,torndb是对python-mysql的封装,不能进行异步操作。但是它很简洁,用起来已经非常习惯了。

    在用Sanic的时候,发现有异步IO的aiomysql可以用,但是用起来还有点麻烦,于是就着手对aiomysql进行封装,既然aiomysql支持连接池,那就直接封装aiomysql.Pool吧。

    代码仓库: https://github.com/veelion/sanicdb

    首先,看看它的初始化

    class SanicDB:
    """A lightweight wrapper around aiomysql.Pool for easy to use
    """
    def __init__(self, host, database, user, password,
                 loop=None, sanic=None,
                 minsize=3, maxsize=5,
                 return_dict=True,
                 pool_recycle=7*3600,
                 autocommit=True,
                 charset = "utf8mb4", **kwargs):
    '''

    前面4个参数是对应数据库的;

    loop 是你的应用程序中的事件循环(event_loop);

    sanic 是你的Sanic 应用中的sanic 对象;

    loop 和 sanic 两者只需提供一个即可,当同时存在时,连接数据库其实用的是sanic里面的loop,这在__init__()代码中可以看到。

    minisize 和 maxsize 是连接池的个数限制;

    return_dict 是返回的数据一条记录为一个dict,key是MySQL表的字段名,value是字段的值;

    pool_recycle 是连接池重连的时间间隔,MySQL默认的连接闲置时间是8小时;

    对MySQL的读写操作方法:

    async def query(self, query, *parameters, **kwparameters): 
    async def execute(self, query, *parameters, **kwparameters):
    async def get(self, query, *parameters, **kwparameters):

    从代码中可以看到,以上三个函数都是调用的cursor的execute() 执行 SQL 命令,但是query(), get() 用于读操作返回数据,query返回全部数据(list),get只返回一条数据。

    execute() 方法用来执行写操作,返回受影响的行ID。

    上面三个函数都是一样的:

    query 是要执行的SQL语句, 后面两个参数是用来参数化执行sql语句的。参数化执行sql是为了防止SQL注入的,那么参数化执行SQL是什么意思呢,举个例子就目标了。

    比如,进行用户登录时,我们要执行一条SQL,Python拼接SQL如下:

    sql = "select * from user where name='%s' and password='%s'" % (input_name, input_password)

    input_name 和 input_password 都是用户输入的,如果用户想捣鬼,他把input_name 输入成 “ ‘ or 1 = 1 –”,拼接出来的sql就成了:

    select * from user where name='' or 1 = 1 --' and password='anything'

    or 后面的 1=1 就是True,而 — 后面都成了注释,这条语句不管input_name, input_password 是什么都可以执行,通过用户验证,达到了注入目的。

    参数化执行SQL就是把拼接SQL的任务交给SanicDB(实际上是它后的aiomysql后面的pymysql),我们只把要拼接的参数当做*parameters传给读写方法即可:

    mydb.query("select * from user where user=%s and password=%s", input_name, input_password)
    更高级的封装:
    

    query(), get(), execute() 就是基本的操作,在此基础上,做了进一步封装,让写应用更方便:

    # 检查一个table中是否含有某字段为某值的记录
    
    async def table_has(self, table_name, field, value):
    
     
    
    # 把一个item插入一个表,item为dict,key是字段名,
    
    # ignore_duplicated为True时,遇到唯一索引重复时不报错
    
    async def table_insert(self, table_name, item, ignore_duplicated=True):
    
     
    
    # 更新一个table的记录,updates是dict,key为字段名
    
    async def table_update(self, table_name, updates, field_where, value_where):

    示例

    代码仓库中有两个示例:

    test.py 是在普通asyncio程序中使用异步MySQL的例子

    example.py 是在Sanic Web中使用的例子

    特别说明一下,Sanic 对象 app 中还没有生成 event_loop 对象(它是在app.run() 之后生成的),所以在Sanic中初始化SanicDB时(app.run())之前,运行sql语句会报错。如果需要创建连接后初始化运行一些SQL操作,可以利用Sanic的Listner:

    @app.listener('before_server_start')
    async def setup_db(app, loop):
        app.db = await db_setup()

    文章首发于我的技术博客猿人学Python基础教程

  • 相关阅读:
    eval()用法
    TTL查看目标的操作系统
    Windows Mobile里用SQLite的 Pinvoke DLL "SQLite.Interop.DLL 异常处理
    创建56个民族的sql语句
    RSS 入门简介
    NAT 网络地址转换
    ARP 攻击
    Python核心数据类型——列表
    Python核心数据类型——字符串
    Linux下 PyDev + Eclipse安装方法
  • 原文地址:https://www.cnblogs.com/amiza/p/10313153.html
Copyright © 2011-2022 走看看