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正则表达式教程之二:捕获篇
Mar 02 Python
python+Splinter实现12306抢票功能
Sep 25 Python
Python读取txt某几列绘图的方法
Oct 14 Python
利用Python实现原创工具的Logo与Help
Dec 03 Python
python print输出延时,让其立刻输出的方法
Jan 07 Python
Python读取stdin方法实例
May 24 Python
python利用re,bs4,requests模块获取股票数据
Jul 29 Python
Windows系统Python直接调用C++ DLL的方法
Aug 01 Python
在Django下创建项目以及设置settings.py教程
Dec 03 Python
django框架基于queryset和双下划线的跨表查询操作详解
Dec 11 Python
Pyinstaller打包Scrapy项目的实现步骤
Sep 22 Python
python excel多行合并的方法
Dec 09 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堆栈与列队的学习
2013/06/21 PHP
Laravel 手动开关 Eloquent 修改器的操作方法
2019/12/30 PHP
tp5框架前台无限极导航菜单类实现方法分析
2020/03/29 PHP
[原创]来自ImageSee官方 JavaScript图片浏览器
2008/01/16 Javascript
JavaScript SHA512&SHA256加密算法详解
2015/08/11 Javascript
JavaScript使ifram跨域相互访问及与PHP通信的实例
2016/03/03 Javascript
jQuery easyui刷新当前tabs的方法
2016/09/23 Javascript
PHP7新特性简述
2017/06/11 Javascript
Nodejs调用WebService的示例代码
2017/09/29 NodeJs
jQuery实现的上传图片本地预览效果简单示例
2018/03/29 jQuery
Vue2.0仿饿了么webapp单页面应用详细步骤
2018/07/08 Javascript
vue-cli监听组件加载完成的方法
2018/09/07 Javascript
简单通过settimeout看javascript的运行机制
2019/05/10 Javascript
npm的lock机制解析
2019/06/20 Javascript
微信小程序把百度地图坐标转换成腾讯地图坐标过程详解
2019/07/10 Javascript
Preload基础使用方法详解
2020/02/03 Javascript
Vue数据双向绑定原理实例解析
2020/05/15 Javascript
pyqt和pyside开发图形化界面
2014/01/22 Python
python持久性管理pickle模块详细介绍
2015/02/18 Python
Python中运行并行任务技巧
2015/02/26 Python
用PyQt进行Python图形界面的程序的开发的入门指引
2015/04/14 Python
python线程、进程和协程详解
2016/07/19 Python
Python 控制终端输出文字的实例
2019/07/12 Python
Python tkinter布局与按钮间距设置方式
2020/03/04 Python
Python基础教程之输入输出和运算符
2020/07/26 Python
详解使用CSS3的@media来编写响应式的页面
2017/11/01 HTML / CSS
size?德国官方网站:英国伦敦的球鞋精品店
2018/03/17 全球购物
导游的职业规划书范文
2013/12/27 职场文书
军训鉴定表自我鉴定
2014/02/13 职场文书
大学生村官承诺书
2014/03/28 职场文书
纪念一二九运动演讲稿
2014/09/16 职场文书
企业法人授权委托书
2014/09/25 职场文书
《丑小鸭》教学反思
2016/02/19 职场文书
工作转正自我鉴定范文
2019/06/21 职场文书
MySQL5.7并行复制原理及实现
2021/06/03 MySQL
如何vue使用el-table遍历循环表头和表体数据
2022/04/26 Vue.js