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的Django框架部署的一些建议
Apr 09 Python
Python构造自定义方法来美化字典结构输出的示例
Jun 16 Python
Python 出现错误TypeError: ‘NoneType’ object is not iterable解决办法
Jan 12 Python
Python排序搜索基本算法之冒泡排序实例分析
Dec 09 Python
python变量赋值方法(可变与不可变)
Jan 12 Python
python实现学员管理系统
Feb 26 Python
python随机数分布random均匀分布实例
Nov 27 Python
python 消费 kafka 数据教程
Dec 21 Python
tensorflow estimator 使用hook实现finetune方式
Jan 21 Python
如何通过python计算圆周率PI
Nov 11 Python
使用django自带的user做外键的方法
Nov 30 Python
Selenium获取登录Cookies并添加Cookies自动登录的方法
Dec 04 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连接access数据库
2015/03/27 PHP
php微信公众平台开发之微信群发信息
2016/09/13 PHP
PHP批量修改文件名称的方法分析
2017/02/27 PHP
php + ajax 实现的写入数据库操作简单示例
2020/05/16 PHP
windows系统php环境安装swoole具体步骤
2021/03/04 PHP
jquery ajax请求实例深入解析
2012/11/26 Javascript
getComputedStyle与currentStyle获取样式(style/class)
2013/03/19 Javascript
解析瀑布流布局:JS+绝对定位的实现
2013/05/08 Javascript
Jquery实现图片左右自动滚动示例
2013/09/25 Javascript
解决html按钮切换绑定不同函数后点击时执行多次函数问题
2014/05/14 Javascript
解决自定义$(id)的方法与jquery选择器$冲突的问题
2014/06/14 Javascript
原生js实现复制对象、扩展对象 类似jquery中的extend()方法
2014/08/30 Javascript
js仿支付宝填写支付密码效果实现多方框输入密码
2016/03/09 Javascript
EasyUI学习之DataGird分页显示数据
2016/12/29 Javascript
Bootstrap布局之栅格系统学习笔记
2017/05/04 Javascript
微信小程序 rich-text的使用方法
2017/08/04 Javascript
vue中使用vue-router切换页面时滚动条自动滚动到顶部的方法
2017/11/28 Javascript
JS运动特效之任意值添加运动的方法分析
2018/01/24 Javascript
详解如何在微信小程序中愉快地使用sass
2018/07/30 Javascript
关于自定义Egg.js的请求级别日志详解
2018/12/12 Javascript
js实现弹幕墙效果
2020/12/10 Javascript
python基础入门学习笔记(Python环境搭建)
2016/01/13 Python
Python实现多线程抓取网页功能实例详解
2017/06/08 Python
python中类的输出或类的实例输出为这种形式的原因
2019/08/12 Python
springboot配置文件抽离 git管理统 配置中心详解
2019/09/02 Python
pytorch 常用函数 max ,eq说明
2020/06/28 Python
Born鞋子官网:Born Shoes
2017/04/06 全球购物
室内设计专业个人的自我评价
2013/10/19 职场文书
三严三实学习心得体会
2014/10/13 职场文书
部门经理迟到检讨书
2015/02/16 职场文书
2015年办公室个人工作总结
2015/04/20 职场文书
女方离婚起诉书
2015/05/18 职场文书
教师旷工检讨书
2015/08/15 职场文书
2016八一建军节慰问信
2015/11/30 职场文书
车位出租协议书范本
2016/03/19 职场文书
CSS中calc(100%-100px)不加空格不生效
2023/05/07 HTML / CSS