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入门篇之条件、循环
Oct 17 Python
python使用点操作符访问字典(dict)数据的方法
Mar 16 Python
Python 基础之字符串string详解及实例
Apr 01 Python
python 表达式和语句及for、while循环练习实例
Jul 07 Python
今天 平安夜 Python 送你一顶圣诞帽 @微信官方
Dec 25 Python
PyQt5打开文件对话框QFileDialog实例代码
Feb 07 Python
深入浅析Python的类
Jun 22 Python
钉钉群自定义机器人消息Python封装的实例
Feb 20 Python
详解python中@的用法
Mar 27 Python
Python3 虚拟开发环境搭建过程(图文详解)
Jan 06 Python
Python列表删除重复元素与图像相似度判断及删除实例代码
May 07 Python
Python数据处理的三个实用技巧分享
Apr 01 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
php中通过curl smtp发送邮件
2012/06/05 PHP
prototype 中文参数乱码解决方案
2009/11/09 Javascript
window.location.hash 属性使用说明
2010/03/20 Javascript
关于JS管理作用域的问题
2013/04/10 Javascript
Javascript alert消息换行的方法
2013/08/07 Javascript
js实现从右向左缓缓浮出网页浮动层广告的方法
2015/05/09 Javascript
jQuery ui实现动感的圆角渐变网站导航菜单效果代码
2015/08/26 Javascript
基于JavaScript如何实现私有成员的语法特征及私有成员的实现方式
2015/10/28 Javascript
基于javascript制作微信聊天面板
2020/08/09 Javascript
jQuery拖拽通过八个点改变div大小
2020/11/29 Javascript
浅谈JavaScript正则表达式-非捕获性分组
2017/03/08 Javascript
bootstrap手风琴折叠示例代码分享
2017/05/22 Javascript
详解angularjs的数组传参方式的简单实现
2017/07/28 Javascript
jQuery实现判断上传图片类型和大小的方法示例
2018/04/11 jQuery
Angular7.2.7路由使用初体验
2019/03/01 Javascript
如何获取vue单文件自身源码路径
2019/05/06 Javascript
解决vue cli使用typescript后打包巨慢的问题
2019/09/30 Javascript
vue使用prop可以渲染但是打印台报错的解决方式
2019/11/13 Javascript
viewer.js一个强大的基于jQuery的图像查看插件(支持旋转、缩放)
2020/04/01 jQuery
11个Javascript小技巧帮你提升代码质量(小结)
2020/12/28 Javascript
[02:50]2014DOTA2 TI预选赛预选赛 大神专访第一弹!
2014/05/21 DOTA
python实现udp数据报传输的方法
2014/09/26 Python
pygame学习笔记(2):画点的三种方法和动画实例
2015/04/15 Python
Python实现的科学计算器功能示例
2017/08/04 Python
flask框架使用orm连接数据库的方法示例
2018/07/16 Python
python 3.3 下载固定链接文件并保存的方法
2018/12/18 Python
对python修改xml文件的节点值方法详解
2018/12/24 Python
对python特殊函数 __call__()的使用详解
2019/07/02 Python
Python 元组拆包示例(Tuple Unpacking)
2019/12/24 Python
HTML5中的postMessage API基本使用教程
2016/05/20 HTML / CSS
高中毕业自我鉴定
2013/12/22 职场文书
物业保安员岗位职责制度
2014/01/30 职场文书
初中体育教学随笔
2015/08/15 职场文书
预备党员的思想汇报,你真的会写吗?
2019/06/28 职场文书
详解python的内存分配机制
2021/05/10 Python
MySQL分布式恢复进阶
2022/07/23 MySQL