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 相关文章推荐
Linux环境下MySQL-python安装过程分享
Feb 02 Python
详细讲解Python中的文件I/O操作
May 24 Python
python基于pygame实现响应游戏中事件的方法(附源码)
Nov 11 Python
一步步解析Python斗牛游戏的概率
Feb 12 Python
实例讲解Python设计模式编程之工厂方法模式的使用
Mar 02 Python
Django1.7+python 2.78+pycharm配置mysql数据库
Oct 09 Python
Django数据库表反向生成实例解析
Feb 06 Python
基于python 爬虫爬到含空格的url的处理方法
May 11 Python
python 实现识别图片上的数字
Jul 30 Python
python关于变量名的基础知识点
Mar 03 Python
python 数据类型强制转换的总结
Jan 25 Python
Python利用socket模块开发简单的端口扫描工具的实现
Jan 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 pcntl_fork和pcntl_fork 的用法
2009/04/13 PHP
php将session放入memcached的设置方法
2014/02/14 PHP
php mb_substr()函数截取中文字符串应用示例
2014/07/29 PHP
php实现字符串首字母转换成大写的方法
2015/03/17 PHP
Symfony生成二维码的方法
2016/02/04 PHP
PHP6连接SQLServer2005的三部曲
2016/04/15 PHP
PHP运用foreach神奇的转换数组(实例讲解)
2018/02/01 PHP
jquery 多行滚动代码(附详细解释)
2010/06/17 Javascript
javascript中类的定义及其方式(《javascript高级程序设计》学习笔记)
2011/07/04 Javascript
JavaScript快速检测浏览器对CSS3特性的支持情况
2012/09/26 Javascript
基于jquery库的tab新形式使用
2012/11/16 Javascript
网页实时显示服务器时间和javscript自运行时钟
2014/06/09 Javascript
JavaScript中利用各种循环进行遍历的方式总结
2015/11/10 Javascript
jQuery easyui的validatebox校验规则扩展及easyui校验框validatebox用法
2016/01/18 Javascript
JavaScript优化专题之Loading and Execution加载和运行
2016/01/20 Javascript
AngularJS实现Model缓存的方式
2016/02/03 Javascript
Angularjs中的页面访问权限怎么设置
2016/11/11 Javascript
vue+axios新手实践实现登陆的示例代码
2018/06/06 Javascript
vue-router命名视图的使用讲解
2019/01/19 Javascript
python应用程序在windows下不出现cmd窗口的办法
2014/05/29 Python
理解python多线程(python多线程简明教程)
2014/06/09 Python
python web基础之加载静态文件实例
2018/03/20 Python
Python3中关于cookie的创建与保存
2018/10/21 Python
简述DNS进行域名解析的过程
2013/12/02 面试题
金额转换,阿拉伯数字的金额转换成中国传统的形式如:(¥1011)-> (一千零一拾一元整)输出
2015/05/29 面试题
GC是什么?为什么要有GC?
2013/12/08 面试题
销售类个人求职信范文
2013/09/25 职场文书
会计与审计专业大专生求职信
2013/10/03 职场文书
中专三年学习的个人自我评价
2013/12/12 职场文书
《穷人》教学反思
2014/04/08 职场文书
代领报检证委托书范本
2014/10/11 职场文书
公司2015年终工作总结
2015/05/26 职场文书
2015年幼儿教育工作总结
2015/07/24 职场文书
用Python进行栅格数据的分区统计和批量提取
2021/05/27 Python
python运算符之与用户交互
2022/04/13 Python
浅谈Node的内存泄露问题
2022/05/06 NodeJs