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 相关文章推荐
Tensorflow环境搭建的方法步骤
Feb 07 Python
python2.7和NLTK安装详细教程
Sep 19 Python
符合语言习惯的 Python 优雅编程技巧【推荐】
Sep 25 Python
APIStar:一个专为Python3设计的API框架
Sep 26 Python
用Python调用win命令行提高工作效率的实例
Aug 14 Python
浅谈python中统计计数的几种方法和Counter详解
Nov 07 Python
Django values()和value_list()的使用
Mar 31 Python
新手学习Python2和Python3中print不同的用法
Jun 09 Python
浅谈matplotlib中FigureCanvasXAgg的用法
Jun 16 Python
python读取xml文件方法解析
Aug 04 Python
Python正则re模块使用步骤及原理解析
Aug 18 Python
Django给表单添加honeypot验证增加安全性
May 06 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 编写的日历
2006/10/09 PHP
十天学会php之第四天
2006/10/09 PHP
PHP数据库开发知多少
2006/10/09 PHP
PHP不用第三变量交换2个变量的值的解决方法
2013/06/02 PHP
php制作简单模版引擎
2016/04/07 PHP
在Thinkphp中使用ajax实现无刷新分页的方法
2016/10/25 PHP
Yii 2.0在Grid中格式化时间方法示例
2017/06/06 PHP
PHP实现的简单对称加密与解密方法实例小结
2017/08/28 PHP
PHP写API输出的时用echo的原因详解
2019/04/28 PHP
PHP超低内存遍历目录文件和读取超大文件的方法
2019/05/01 PHP
JQuery each打印JS对象的方法
2013/11/13 Javascript
js实例属性和原型属性示例详解
2014/11/23 Javascript
jquery中checkbox全选失效的解决方法
2014/12/26 Javascript
JavaScript 链式结构序列化详解
2016/09/30 Javascript
使用jQuery和ajax代替iframe的方法(详解)
2017/04/12 jQuery
简单实现js上传文件功能
2017/08/21 Javascript
Vue 项目中遇到的跨域问题及解决方法(后台php)
2018/03/28 Javascript
vue中各选项及钩子函数执行顺序详解
2018/08/25 Javascript
vue.js 2.0实现简单分页效果
2019/07/29 Javascript
vue ajax 拦截原理与实现方法示例
2019/11/29 Javascript
[00:47]DOTA2荣耀之路6:玩不了啦!
2018/05/30 DOTA
python自动翻译实现方法
2016/05/28 Python
tensorflow建立一个简单的神经网络的方法
2018/02/10 Python
Python3爬取英雄联盟英雄皮肤大图实例代码
2018/11/14 Python
python实现文件的备份流程详解
2019/06/18 Python
python系统指定文件的查找只输出目录下所有文件及文件夹
2020/01/19 Python
python生成13位或16位时间戳以及反向解析时间戳的实例
2020/03/03 Python
Kears 使用:通过回调函数保存最佳准确率下的模型操作
2020/06/17 Python
基于PyTorch中view的用法说明
2021/03/03 Python
data:image data url 文件转为Blob上传后端的方法
2019/07/16 HTML / CSS
在家更换处方镜片:Lensabl
2019/05/01 全球购物
介绍一下HTTP、HTTPS和SSL
2012/12/16 面试题
linux比较文件内容的命令是什么
2015/09/23 面试题
玄武湖导游词
2015/02/05 职场文书
遗失证明范文
2015/06/19 职场文书
毕业论文答辩稿范文
2015/06/23 职场文书