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升级提示Tkinter模块找不到的解决方法
Aug 22 Python
Python中使用ElementTree解析XML示例
Jun 02 Python
Python的Flask框架中的Jinja2模板引擎学习教程
Jun 30 Python
Python中正则表达式的用法总结
Feb 22 Python
Python multiprocessing多进程原理与应用示例
Feb 28 Python
pybind11在Windows下的使用教程
Jul 04 Python
Python将文字转成语音并读出来的实例详解
Jul 15 Python
Python Pillow.Image 图像保存和参数选择方式
Jan 09 Python
python对Excel的读取的示例代码
Feb 14 Python
python打包生成so文件的实现
Oct 30 Python
selenium3.0+python之环境搭建的方法步骤
Feb 01 Python
Python办公自动化之教你用Python批量识别发票并录入到Excel表格中
Jun 26 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
咖啡语言
2021/03/03 咖啡文化
php smarty 二级分类代码和模版循环例子
2011/06/16 PHP
深入php-fpm的两种进程管理模式详解
2013/06/03 PHP
PHP函数microtime()用法与说明
2013/12/04 PHP
CI框架装载器Loader.php源码分析
2014/11/04 PHP
php+xml结合Ajax实现点赞功能完整实例
2015/01/30 PHP
php中使用in_array() foreach array_search() 查找数组是否包含时的性能对比
2015/04/14 PHP
深入探究PHP的多进程编程方法
2015/08/18 PHP
详细解读php的命名空间(一)
2018/02/21 PHP
PHP接入微信H5支付的方法示例
2019/10/28 PHP
WordPress伪静态规则设置代码实例
2020/12/10 PHP
JavaScript脚本性能优化注意事项
2008/11/18 Javascript
jQuery autocomplate 自扩展插件、自动完成示例代码
2011/03/28 Javascript
Javascript模块化编程(一)AMD规范(规范使用模块)
2013/01/17 Javascript
Javascript 修改String 对象 增加去除空格功能(示例代码)
2013/11/30 Javascript
firefox下jquery ajax返回object XMLDocument处理方法
2014/01/26 Javascript
JavaScript仿商城实现图片广告轮播实例代码
2016/02/06 Javascript
jQuery实现手机自定义弹出输入框
2016/06/13 Javascript
微信小程序 action-sheet底部菜单详解
2016/10/27 Javascript
基于React+Redux的SSR实现方法
2018/07/03 Javascript
[02:04]2014DOTA2国际邀请赛 BBC小组赛第三天总结
2014/07/12 DOTA
约瑟夫问题的Python和C++求解方法
2015/08/20 Python
使用python编写udp协议的ping程序方法
2018/04/22 Python
深入浅析python 中的匿名函数
2018/05/21 Python
Anaconda之conda常用命令介绍(安装、更新、删除)
2019/10/06 Python
python实现简单飞行棋
2020/02/06 Python
浅谈Selenium+Webdriver 常用的元素定位方式
2021/01/13 Python
Python爬虫爬取微博热搜保存为 Markdown 文件的源码
2021/02/22 Python
新闻专业个人自我评价
2013/09/21 职场文书
工厂总经理岗位职责
2014/02/07 职场文书
2015年幼儿园中班开学寄语
2015/05/27 职场文书
雷锋电影观后感
2015/06/10 职场文书
企业法人代表证明书
2015/06/18 职场文书
新闻通讯稿范文
2015/07/22 职场文书
导游词之河姆渡遗址博物馆
2019/10/10 职场文书
Mybatis-plus在项目中的简单应用
2021/07/01 Java/Android