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命令行解析工具Argparse
Apr 20 Python
Python2.7基于淘宝接口获取IP地址所在地理位置的方法【测试可用】
Jun 07 Python
利用python实现xml与数据库读取转换的方法
Jun 17 Python
Python通过matplotlib绘制动画简单实例
Dec 13 Python
浅析python实现scrapy定时执行爬虫
Mar 04 Python
python多维数组切片方法
Apr 13 Python
基于Python pip用国内镜像下载的方法
Jun 12 Python
教你利用Python玩转histogram直方图的五种方法
Jul 30 Python
解决Pycharm出现的部分快捷键无效问题
Oct 22 Python
详解python解压压缩包的五种方法
Jul 05 Python
spyder 在控制台(console)执行python文件,debug python程序方式
Apr 20 Python
python3:excel操作之读取数据并返回字典 + 写入的案例
Sep 01 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
正则表达式语法
2006/10/09 Javascript
php 获取远程网页内容的函数
2009/09/08 PHP
thinkphp的dump函数无输出实例代码
2016/11/15 PHP
PHP的mysqli_set_charset()函数讲解
2019/01/23 PHP
HTA版JSMin(省略修饰语若干)基于javascript语言编写
2009/12/24 Javascript
让firefox支持IE的一些方法的javascript扩展函数代码
2010/01/02 Javascript
javascript 密码强度验证规则、打分、验证(给出前端代码,后端代码可根据强度规则翻译)
2010/05/18 Javascript
javascript中使用css需要注意的地方小结
2010/09/01 Javascript
js中的数组Array定义与sort方法使用示例
2013/08/29 Javascript
setTimeout和setInterval的深入理解
2013/11/08 Javascript
jQuery中extend函数的实现原理详解
2015/02/03 Javascript
javascript结合canvas实现图片旋转效果
2015/05/03 Javascript
JavaScript中利用jQuery绑定事件的几种方式小结
2016/03/06 Javascript
jQuery子元素过滤选择器用法示例
2016/09/09 Javascript
ES6 javascript中class类的get与set用法实例分析
2017/10/30 Javascript
Bootstrap Fileinput 4.4.7文件上传实例详解
2018/07/25 Javascript
layui从数据库中获取复选框的值并默认选中方法
2018/08/15 Javascript
node.js基于socket.io快速实现一个实时通讯应用
2019/04/23 Javascript
在mpvue框架中使用Vant WeappUI组件库的注意事项【推进】
2019/06/09 Javascript
js实现提交前对列表数据的增删改查
2020/01/16 Javascript
解决vue单页面 回退页面 keeplive 缓存问题
2020/07/22 Javascript
Kettle中使用JavaScrip调用jar包对文件内容进行MD5加密的操作方法
2020/09/04 Javascript
Webpack5正式发布,有哪些新特性
2020/10/12 Javascript
element 动态合并表格的步骤
2020/12/31 Javascript
python数据库操作常用功能使用详解(创建表/插入数据/获取数据)
2013/12/06 Python
在python3环境下的Django中使用MySQL数据库的实例
2017/08/29 Python
Python使用Scrapy保存控制台信息到文本解析
2017/12/27 Python
基于python实现雪花算法过程详解
2019/11/16 Python
Python搭建HTTP服务过程图解
2019/12/14 Python
Pytorch 数据加载与数据预处理方式
2019/12/31 Python
马德里运动鞋商店:Nigra Mercato
2020/02/16 全球购物
后勤园长自我鉴定
2013/10/17 职场文书
授权委托书范本(单位)
2014/09/28 职场文书
Python中os模块的简单使用及重命名操作
2021/04/17 Python
MongoDB orm框架的注意事项及简单使用
2021/06/20 MongoDB
vue @click.native 绑定原生点击事件
2022/04/22 Vue.js