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常用的日期时间处理方法示例
Feb 08 Python
Python实现设置windows桌面壁纸代码分享
Mar 28 Python
Python Socket编程详细介绍
Mar 23 Python
python中defaultdict的用法详解
Jun 07 Python
基于python的Tkinter编写登陆注册界面
Jun 30 Python
Python中一行和多行import模块问题
Apr 01 Python
Python函数参数操作详解
Aug 03 Python
Python实现的在特定目录下导入模块功能分析
Feb 11 Python
值得收藏的10道python 面试题
Apr 15 Python
python画微信表情符的实例代码
Oct 09 Python
运行Python编写的程序方法实例
Oct 21 Python
用python对oracle进行简单性能测试
Dec 05 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入门学习知识点七 PHP函数的基本应用
2011/07/14 PHP
php中设置index.php文件为只读的方法
2013/02/06 PHP
php接口数据加密、解密、验证签名
2015/03/12 PHP
php实现用于删除整个目录的递归函数
2015/03/16 PHP
thinkPHP下ueditor的使用方法详解
2015/12/26 PHP
PHP编程 SSO详细介绍及简单实例
2017/01/13 PHP
php连接MSsql server的五种方法总结
2018/03/04 PHP
node.js中的favicon.ico请求问题处理
2014/12/15 Javascript
浅谈JavaScript正则表达式分组匹配
2015/04/10 Javascript
Hammer.js+轮播原理实现简洁的滑屏功能
2016/02/02 Javascript
Angular学习笔记之集成三方UI框架、控件的示例
2018/03/23 Javascript
angularJS开发注意事项
2018/05/26 Javascript
js运算符的一些特殊用法
2018/07/29 Javascript
基于Vue 实现一个中规中矩loading组件
2019/04/03 Javascript
关于vue路由缓存清除在main.js中的设置
2019/11/06 Javascript
[02:28]DOTA2英雄基础教程 灰烬之灵
2013/12/19 DOTA
[05:46]2018完美盛典-《同梦共竞》
2018/12/17 DOTA
[47:31]完美世界DOTA2联赛PWL S3 INK ICE vs DLG 第一场 12.12
2020/12/16 DOTA
python中mechanize库的简单使用示例
2014/01/10 Python
python BeautifulSoup设置页面编码的方法
2015/04/03 Python
python操作mongodb根据_id查询数据的实现方法
2015/05/20 Python
python3.5 email实现发送邮件功能
2018/05/22 Python
Python 面试中 8 个必考问题
2018/11/16 Python
详解安装mitmproxy以及遇到的坑和简单用法
2019/01/21 Python
WxPython建立批量录入框窗口
2019/02/27 Python
十分钟搞定pandas(入门教程)
2019/06/21 Python
使用Python和Scribus创建一个RGB立方体的方法
2019/07/17 Python
Python基于locals返回作用域字典
2020/10/17 Python
Python+OpenCV图像处理—— 色彩空间转换
2020/10/22 Python
Laura Geller官网:美国彩妆品牌
2018/12/29 全球购物
销售行业个人求职自荐信
2013/09/25 职场文书
给老师的一封建议书
2014/03/13 职场文书
经销商订货会主持词
2014/03/27 职场文书
小学生学雷锋演讲稿
2014/04/25 职场文书
人民检察院起诉书
2015/05/20 职场文书
导游词之云南丽江古城
2019/09/17 职场文书