Python操作sqlite3快速、安全插入数据(防注入)的实例


Posted in Python onApril 26, 2014

table通过使用下面语句创建:

create table userinfo(name text, email text)

更快地插入数据

在此用time.clock()来计时,看看以下三种方法的速度。

import sqlite3
import time
def create_tables(dbname):  
    conn = sqlite3.connect(dbname)
    cursor = conn.cursor()
    cursor.execute('''create table userinfo(name text, email text)''')
    conn.commit()
    cursor.close()
    conn.close()
def drop_tables(dbname):
    conn = sqlite3.connect(dbname)
    cursor = conn.cursor()
    cursor.execute('''drop table userinfo''')
    conn.commit()
    cursor.close()
    conn.close()
def insert1():
    users = [('qq','qq@example.com'),
            ('ww','ww@example.com'),
            ('ee','ee@example.com'),
            ('rr','rr@example.com'),
            ('tt','tt@example.com'),
            ('yy','yy@example.com'),
            ('uu','uu@example.com')
            ]
    start = time.clock()
    conn = sqlite3.connect(dbname)
    cursor = conn.cursor()
    for user in users:
        cursor.execute("insert into userinfo(name, email) values(?, ?)", user)
        conn.commit()
    cursor.close()
    conn.close()
    end = time.clock()
    print start, end, end-start
def insert2():
    users = [('qq','qq@example.com'),
            ('ww','ww@example.com'),
            ('ee','ee@example.com'),
            ('rr','rr@example.com'),
            ('tt','tt@example.com'),
            ('yy','yy@example.com'),
            ('uu','uu@example.com')
            ]
    start = time.clock()
    conn = sqlite3.connect(dbname)
    cursor = conn.cursor()
    for user in users:
        cursor.execute("insert into userinfo(name, email) values(?, ?)", user)
    conn.commit()
    cursor.close()
    conn.close()
    end = time.clock()
    print start, end, end-start
def insert3():
    users = [('qq','qq@example.com'),
            ('ww','ww@example.com'),
            ('ee','ee@example.com'),
            ('rr','rr@example.com'),
            ('tt','tt@example.com'),
            ('yy','yy@example.com'),
            ('uu','uu@example.com')
            ]
    start = time.clock()
    conn = sqlite3.connect(dbname)
    cursor = conn.cursor()
    cursor.executemany("insert into userinfo(name, email) values(?, ?)", users)
    conn.commit()
    cursor.close()
    conn.close()
    end = time.clock()
    print start, end, end-start
if __name__ == '__main__':
    dbname = 'test.db'
    create_tables(dbname)
    insert1()
    drop_tables(dbname)
    create_tables(dbname)
    insert2()
    drop_tables(dbname)
    create_tables(dbname)
    insert3()
    drop_tables(dbname)

某次运行结果:

4.05223164501e-07 0.531585119557 0.531584714334
0.755963264089 0.867329935942 0.111366671854
1.0324360882 1.12175173111 0.0893156429109

另外一次运行结果:
4.05223164501e-07 0.565988971446 0.565988566223
0.768132520942 0.843723660494 0.0755911395524
1.04367819446 1.13247636739 0.0887981729298

在运行结果中,第三列表示插入数据使用的时间。综合看来,方法insert1()的速度很慢,原因在于每次insert都commit()。

更安全地操作数据库

先上代码:

import sqlite3
def create_tables(dbname):  
    conn = sqlite3.connect(dbname)
    cursor = conn.cursor()
    cursor.execute('''create table userinfo(name text, email text)''')
    conn.commit()
    cursor.close()
    conn.close()
def drop_tables(dbname):
    conn = sqlite3.connect(dbname)
    cursor = conn.cursor()
    cursor.execute('''drop table userinfo''')
    conn.commit()
    cursor.close()
    conn.close()
def insert():
    users = [('qq','qq@example.com'),
            ('ww','ww@example.com'),
            ('ee','ee@example.com'),
            ('rr','rr@example.com'),
            ('tt','tt@example.com'),
            ('yy','yy@example.com'),
            ('uu','uu@example.com')
            ]
    conn = sqlite3.connect(dbname)
    cursor = conn.cursor()
    cursor.executemany("insert into userinfo(name, email) values(?, ?)", users)
    conn.commit()
    cursor.close()
    conn.close()
def insecure_select(text):
    conn = sqlite3.connect(dbname)
    cursor = conn.cursor()
    print "select name from userinfo where email='%s'" % text
    for row in cursor.execute("select name from userinfo where email='%s'" % text):
        print row
def secure_select(text):
    conn = sqlite3.connect(dbname)
    cursor = conn.cursor()
    print "select name from userinfo where email='%s'" % text
    for row in cursor.execute("select name from userinfo where email= ? ", (text,)):
        print row
if __name__ == '__main__':
    dbname = 'test.db'
    create_tables(dbname)
    insert()
    insecure_select("uu@example.com")
    insecure_select("' or 1=1;--")
    secure_select("uu@example.com")
    secure_select("' or 1=1;--")
    drop_tables(dbname)

运行结果:
select name from userinfo where email='uu@example.com'
(u'uu',)
select name from userinfo where email='' or 1=1;--'
(u'qq',)
(u'ww',)
(u'ee',)
(u'rr',)
(u'tt',)
(u'yy',)
(u'uu',)
select name from userinfo where email='uu@example.com'
(u'uu',)
select name from userinfo where email='' or 1=1;--'

函数insecure_select(text)和secure_select(text)的本意都是根据email获取对应的用户名信息。但是insecure_select(text)的实现容易引起sql注入。

insecure_select("' or 1=1;--")便是一个例子。在insecure_select()中cursor.execute()只有一个参数,即sql语句,这个生成的sql语句如果有问题,还是会照常执行。

secure_select(text)的实现可以防止sql注入,cursor.execute()的第一个参数使用了占位符?表示要被替代的内容,第二个参数指定每个占位符对应的值,在底层实现上,这种方法(至少)转义了特殊字符,可以防止sql注入。

Python 相关文章推荐
用实例详解Python中的Django框架中prefetch_related()函数对数据库查询的优化
Apr 01 Python
通过Python来使用七牛云存储的方法详解
Aug 07 Python
Linux上安装Python的PIL和Pillow库处理图片的实例教程
Jun 23 Python
Python双精度浮点数运算并分行显示操作示例
Jul 21 Python
Python实现的简单读写csv文件操作示例
Jul 12 Python
pandas 将索引值相加的方法
Nov 15 Python
python 求某条线上特定x值或y值的点坐标方法
Jul 09 Python
python生成器推导式用法简单示例
Oct 08 Python
python Pillow图像处理方法汇总
Oct 16 Python
Python内置类型性能分析过程实例
Jan 29 Python
python range实例用法分享
Feb 06 Python
python playwright 自动等待和断言详解
Nov 27 Python
python实现的二叉树算法和kmp算法实例
Apr 25 #Python
python中的__init__ 、__new__、__call__小结
Apr 25 #Python
Python yield 小结和实例
Apr 25 #Python
python计数排序和基数排序算法实例
Apr 25 #Python
python处理圆角图片、圆形图片的例子
Apr 25 #Python
python实现的阳历转阴历(农历)算法
Apr 25 #Python
Python实现的简单万年历例子分享
Apr 25 #Python
You might like
Zend引擎的发展 [15]
2006/10/09 PHP
PHP删除特定数组内容并且重建数组索引的方法.
2011/03/25 PHP
免费手机号码归属地API查询接口和PHP使用实例分享
2014/04/10 PHP
学习php设计模式 php实现装饰器模式(decorator)
2015/12/07 PHP
PHP连接MYSQL数据库实例代码
2016/01/20 PHP
php中Redis的应用--消息传递
2017/03/28 PHP
图片自动缩小的js代码,用以防止图片撑破页面
2007/03/12 Javascript
javascript据option的value值快速设定初始的selected选项
2007/08/13 Javascript
JQuery处理json与ajax返回JSON实例代码
2014/01/03 Javascript
node.js中的path.delimiter方法使用说明
2014/12/09 Javascript
JS实现的多张图片轮流播放幻灯片效果
2016/07/22 Javascript
vue-cli3.0配置及使用注意事项详解
2018/09/05 Javascript
JS div匀速移动动画与变速移动动画代码实例
2019/03/26 Javascript
深入浅析Vue 中 ref 的使用
2019/04/29 Javascript
vue简单练习 桌面时钟的实现代码实例
2019/09/19 Javascript
layui table复选框禁止某几条勾选的实例
2019/09/20 Javascript
Vue页面刷新记住页面状态的实现
2019/12/27 Javascript
JS面向对象编程基础篇(二) 封装操作实例详解
2020/03/03 Javascript
Javascript前端下载后台传来的文件流代码实例
2020/08/18 Javascript
微信小程序实现分页加载效果
2020/11/19 Javascript
Python使用回溯法子集树模板解决迷宫问题示例
2017/09/01 Python
TensorFlow平台下Python实现神经网络
2018/03/10 Python
Python比较2个时间大小的实现方法
2018/04/10 Python
python 获取一个值在某个区间的指定倍数的值方法
2018/11/12 Python
详解pyenv下使用python matplotlib模块的问题解决
2018/11/29 Python
Python selenium模块实现定位过程解析
2020/07/09 Python
欧洲最大的笔和书写专家:The Pen Shop
2017/03/19 全球购物
美国名牌太阳镜折扣网站:Eyedictive
2017/05/15 全球购物
埃弗顿足球俱乐部官方网上商店:Everton Direct
2018/01/13 全球购物
Cult Gaia官网:美国生活方式品牌
2019/08/16 全球购物
党员党性分析材料
2014/02/17 职场文书
勤奋学习演讲稿
2014/05/10 职场文书
消防标语大全
2014/06/07 职场文书
爱心捐书倡议书
2015/04/27 职场文书
我是特种兵观后感
2015/06/11 职场文书
公务员岗前培训心得体会
2016/01/08 职场文书