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 相关文章推荐
Anaconda下安装mysql-python的包实例
Jun 11 Python
解决python通过cx_Oracle模块连接Oracle乱码的问题
Oct 18 Python
解决项目pycharm能运行,在终端却无法运行的问题
Jan 19 Python
Django 大文件下载实现过程解析
Aug 01 Python
详解Django-channels 实现WebSocket实例
Aug 22 Python
python时间与Unix时间戳相互转换方法详解
Feb 13 Python
pytorch进行上采样的种类实例
Feb 18 Python
使用Python将图片转正方形的两种方法实例代码详解
Apr 29 Python
python读取hdfs并返回dataframe教程
Jun 05 Python
Python如何将模块打包并发布
Aug 30 Python
详解KMP算法以及python如何实现
Sep 18 Python
python 实现aes256加密
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
PHP copy函数使用案例代码解析
2020/09/01 PHP
基于Jquery的将DropDownlist的选中值赋给label的实现代码
2011/05/06 Javascript
关于js datetime的那点事
2011/11/15 Javascript
js操纵跨frame的三级联动select下拉选项实例介绍
2013/05/19 Javascript
利用javascript判断文件是否存在
2013/12/31 Javascript
php中给js数组赋值方法
2014/03/10 Javascript
JS实现单行文字不间断向上滚动的方法
2015/01/29 Javascript
Javascript实现颜色rgb与16进制转换的方法
2015/04/18 Javascript
javascript实现的字符串与十六进制表示字符串相互转换方法
2015/07/17 Javascript
Bootstrap安装环境配置教程分享
2016/05/27 Javascript
解决wx.onMenuShareTimeline出现的问题
2016/08/16 Javascript
Node学习记录之cluster模块
2017/05/31 Javascript
JS中使用gulp实现压缩文件及浏览器热加载功能
2017/07/12 Javascript
Vue.js项目部署到服务器的详细步骤
2017/07/17 Javascript
微信小程序实现带缩略图轮播效果
2018/11/04 Javascript
node错误处理与日志记录的实现
2018/12/24 Javascript
layui内置模块layim发送图片添加加载动画的方法
2019/09/23 Javascript
python基础教程之python消息摘要算法使用示例
2014/02/10 Python
Python os模块中的isfile()和isdir()函数均返回false问题解决方法
2015/02/04 Python
python实现用于测试网站访问速率的方法
2015/05/26 Python
python抓取网页内容并进行语音播报的方法
2018/12/24 Python
python获取txt文件词向量过程详解
2019/07/05 Python
基于MATLAB和Python实现MFCC特征参数提取
2019/08/13 Python
如何使用python传入不确定个数参数
2020/02/18 Python
python Socket网络编程实现C/S模式和P2P
2020/06/22 Python
浅谈python出错时traceback的解读
2020/07/15 Python
详解CSS3 弹性布局快速入门
2019/06/06 HTML / CSS
意大利制造的男鞋和女鞋:SCAROSSO
2018/03/07 全球购物
英国伦敦的睡衣品牌:Asceno
2019/10/06 全球购物
英国时尚配饰、珠宝和服装网站:KJ Beckett
2020/01/23 全球购物
工厂保安员岗位职责
2014/01/31 职场文书
财务部总监岗位职责
2014/03/12 职场文书
网络技术专业求职信
2014/07/13 职场文书
安全生产月标语
2014/10/07 职场文书
小学教师师德培训心得体会
2016/01/09 职场文书
详解php中流行的rpc框架
2021/05/29 PHP