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获取赶集网招聘信息前篇
Apr 18 Python
在Python的Flask框架中构建Web表单的教程
Jun 04 Python
Python简单格式化时间的方法【strftime函数】
Sep 18 Python
Python切换pip安装源的方法详解
Nov 18 Python
python引入导入自定义模块和外部文件的实例
Jul 24 Python
python方向键控制上下左右代码
Jan 20 Python
Python函数装饰器常见使用方法实例详解
Mar 30 Python
python自定义函数实现最大值的输出方法
Jul 09 Python
Python学习笔记之Break和Continue用法分析
Aug 14 Python
python如果快速判断数字奇数偶数
Nov 13 Python
手动安装python3.6的操作过程详解
Jan 13 Python
Python基础之进程详解
May 21 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
PHPMailer邮件类利用smtp.163.com发送邮件方法
2008/09/11 PHP
php 模拟GMAIL,HOTMAIL(MSN),YAHOO,163,126邮箱登录的详细介绍
2013/06/18 PHP
PHP实现将科学计数法转换为原始数字字符串的方法
2014/12/16 PHP
PHP SplObjectStorage使用实例
2015/05/12 PHP
php实现读取和写入tab分割的文件
2015/06/01 PHP
laravel5.2实现区分前后台用户登录的方法
2017/01/11 PHP
php实现头像上传预览功能
2017/04/27 PHP
php中文乱码问题的终极解决方案汇总
2017/08/01 PHP
怎么用javascript进行拖拽
2006/07/20 Javascript
JS效率个人经验谈(8-15更新),加入range技巧
2007/01/09 Javascript
JavaScript 字符串连接性能优化
2008/12/20 Javascript
关于图片按比例自适应缩放的js代码
2011/10/30 Javascript
利用javascript判断文件是否存在
2013/12/31 Javascript
JqueryMobile动态生成listView并实现刷新的两种方法
2014/03/05 Javascript
jQuery使用andSelf()来包含之前的选择集
2014/05/19 Javascript
浅谈javascript的call()、apply()、bind()的用法
2016/02/21 Javascript
AngularJS发送异步Get/Post请求方法
2018/08/13 Javascript
详解element-ui设置下拉选择切换必填和非必填
2019/06/17 Javascript
深入了解query和params的使用区别
2019/06/24 Javascript
Layui 动态禁止select下拉的例子
2019/09/03 Javascript
JS实现json数组排序操作实例分析
2019/10/28 Javascript
微信小程序实用代码段(收藏版)
2019/12/17 Javascript
vue使用svg文件补充-svg放大缩小操作(使用d3.js)
2020/09/22 Javascript
Python自定义线程池实现方法分析
2018/02/07 Python
python实现windows下文件备份脚本
2018/05/27 Python
pyqt5对用qt designer设计的窗体实现弹出子窗口的示例
2019/06/19 Python
英国现代市场:ARKET
2019/04/10 全球购物
德国药房apodiscounter中文官网:德国排名前三的网上药店
2019/06/03 全球购物
Skechers越南官方网站:来自美国的运动休闲品牌
2021/02/22 全球购物
外包公司软件测试工程师
2014/11/01 面试题
实习自我鉴定
2013/12/15 职场文书
养生餐厅创业计划书范文
2014/03/26 职场文书
投资意向书范本
2014/04/01 职场文书
2015年环保局工作总结
2015/05/22 职场文书
公文写作:工伤事故分析报告怎么写?
2019/11/05 职场文书