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正则分组的应用
Nov 10 Python
python定时器(Timer)用法简单实例
Jun 04 Python
使用Python写个小监控
Jan 27 Python
Python实现模拟分割大文件及多线程处理的方法
Oct 10 Python
Python 中Pickle库的使用详解
Feb 24 Python
详解Django 中是否使用时区的区别
Jun 14 Python
Python调用服务接口的实例
Jan 03 Python
Flask框架学习笔记之使用Flask实现表单开发详解
Aug 12 Python
在django-xadmin中APScheduler的启动初始化实例
Nov 15 Python
python实现对变位词的判断方法
Apr 05 Python
Python内置函数locals和globals对比
Apr 28 Python
python删除某个目录文件夹的方法
May 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
在WIN98下以apache模块方式安装php
2006/10/09 PHP
php中获得视频时间总长度的另一种方法
2011/09/15 PHP
php中error与exception的区别及应用
2014/07/28 PHP
PHP调试函数和日志记录函数分享
2015/01/31 PHP
PHP图片添加水印功能示例小结
2016/10/03 PHP
Javascript图像处理—平滑处理实现原理
2012/12/28 Javascript
jquery高效反选具体实现
2013/05/05 Javascript
div模拟滚动条效果示例代码
2013/10/16 Javascript
js中opener与parent的区别详细解析
2014/01/14 Javascript
jQuery插件jFade实现鼠标经过的图片高亮其它变暗
2015/03/14 Javascript
jQuery实现图片局部放大镜效果
2016/03/17 Javascript
详解Vue2+Echarts实现多种图表数据可视化Dashboard(附源码)
2017/03/21 Javascript
jQuery实现动态显示select下拉列表数据的方法
2018/02/05 jQuery
js经验分享 JavaScript反调试技巧
2018/03/10 Javascript
JS实现对json对象排序并删除id相同项功能示例
2018/04/18 Javascript
Bootstrap的aria-label和aria-labelledby属性实例详解
2018/11/02 Javascript
Vue-Cli 3.0 中配置高德地图的两种方式
2019/06/19 Javascript
p5.js实现故宫橘猫赏秋图动画
2019/10/23 Javascript
python中split方法用法分析
2015/04/17 Python
对python中矩阵相加函数sum()的使用详解
2019/01/28 Python
django项目简单调取百度翻译接口的方法
2019/08/06 Python
python中几种自动微分库解析
2019/08/29 Python
详解mac python+selenium+Chrome 简单案例
2019/11/08 Python
Python面向对象之多态原理与用法案例分析
2019/12/30 Python
Python用input输入列表的实例代码
2020/02/07 Python
Python实现屏幕录制功能的代码
2020/03/02 Python
如何基于Python pygame实现动画跑马灯
2020/11/18 Python
全球酒店比价网:HotelsCombined
2017/06/20 全球购物
最新党员的自我评价分享
2013/11/04 职场文书
应聘面试自我评价
2014/01/24 职场文书
面临毕业的毕业生自荐书范文
2014/02/05 职场文书
个人授权委托书范文
2014/09/21 职场文书
先进个人申报材料
2014/12/30 职场文书
小人国观后感
2015/06/11 职场文书
关于JavaScript回调函数的深入理解
2021/06/27 Javascript
SpringBoot2零基础到精通之异常处理与web原生组件注入
2022/03/22 Java/Android