不同数据库还是有各自特点的,之前自以为熟悉mysql,然后全都照搬到sqlite3上,这样果然是不行的。笔者就近期在使用sqlite3时碰到的问题做了总结分析,并给出相应解决方法,供大家参考。

1、如何insert一条记录?

示例如下,其中sql语句中的%d、’%s’均为占位符,注意字符串占位符需要加引号,在执行时会被%(…)中的mid、mname等变量替换。

import sqlite3
conn = sqlite3.connect("movie.db")
msql = "insert into movieinfo(mid,mname, myear, mgenre, mruntime, rank, mrating, link) values(%d, '%s', %d, '%s','%s', '%s', %f, '%s')"%(mid, mname, myear, mgenre, mruntime, rank,mrating, link)
conn.execute(msql)

2、如何清空数据表?

示例如下。sql标准中有TRUNCATE TABLE语句,用来清空表的所有内容;对于大多数DBMS来说,用DELETE不如用TRUNCATE速度快,但sqlite3不支持该语句。在sqlite3中直接使用“DELETE FROM TableName”就行,而且它对DELETE做了优化,速度比普通的逐条DELETE要快得多。

dsql = "delete from movieinfo"
conn.execute(dsql)

3、如果待insert的变量中有单引号?

如果变量中有单引号,例如待插入的字符串变量mname值为movie’s name,变量中的单引号会和占位符’%s’外的引号产生闭合,从而导致插入错误。而且这样的单引号如果被黑客利用,可能导致程序被sql注入的安全问题。

最好的解决方案,是遵循官方建议,不用诸如%d和’%s’的占位符,而统一用?作为占位符,这样sqlite3会根据情况自动处理字符串中的各种特殊字符;不仅可以避免插入错误,也可以有效防止程序被入侵。示例如下,注意%要用,替换:

msql = "insert into movieinfo(mid,mname, myear, mgenre, mruntime, rank, mrating, link) values(?, ?, ?, ?, ?, ?, ?,?)", (mid, mname, myear, mgenre, mruntime, rank, mrating, link)
conn.execute(msql)

4、如果待insert的变量中有Unicode字符?

如果变量中有unicode字符,例如待插入的字符串变量mname值为u'\u4e2d\u6587';此时如采用问题3中的sql语句,也依然会出现无法成功插入的问题。此时,可以使用带参数的sql语句处理,示例如下:

msql = "insert into movieinfo(mid,mname, myear, mgenre, mruntime, rank, mrating, link) values(?, ?, ?, ?, ?, ?, ?,?)"
parameter = [mid, mname, myear, mgenre,mruntime, rank, mrating, link]
conn.execute(msql, parameter)

5、如果待insert的变量中存在主键重复问题?

当原始数据中存在主键重复(例如:id)的记录,我们又想将所有记录插入到数据库中,可以使用insert or replace语句。这样,id重复的记录只保留最后一项(即先插入的记录被后插入的记录替换),示例如下:

msql = "insert or replace intomovieinfo(mid, mname, myear, mgenre, mruntime, rank, mrating, link) values(?, ?,?, ?, ?, ?, ?, ?)"
parameter = [mid, mname, myear, mgenre,mruntime, rank, mrating, link]
conn.execute(msql, parameter)

6、如果想一次insert多条记录?

虽然无法使用预先准备的多条sql语句进行批量insert操作,但sqlite3依然提供同时插入多条记录的工具executemany()。示例如下,注意execute()语句已经更换为executemany():

msql = "insert or replace intomovieinfo(mid, mname, myear, mgenre, mruntime, rank, mrating, link) values(?, ?,?, ?, ?, ?, ?, ?)"
parameters = [(mid1, mname1, myear1, mgenre1,mruntime1, rank1, mrating1, link1), (mid2, mname2, myear2, mgenre2, mruntime2,rank2, mrating2, link2)]
conn.executemany(msql, parameters)

7、如果出现”database islocked”问题?

相信会有不少人碰到OperationalError: database is locked问题,网上最常见的解释是sqlite3不支持多线程操作,如果多个进程同时操作同一个数据库会导致数据库锁死。此时,如果问题重复出现,可能需要考虑换数据库。

但是另一种可能性其实是,在一些操作没有结束时,就进行了下一步的操作(可以通过检查文件下是否有一个*.db-journal文件来确认,正常是没有此文件的)。例如现在执行conn.execute("delete from movieinfo"),文件夹下会产生一个movieinfo.db-journal文件,表明该会话没有处理完成;此时如果对数据库做其它操作,则会抛出“OperationalError: database is locked”异常。

如果在执行完清空数据表操作后,立即提交conn.commit(),则.db-journal文件消失,表明所有会话已经完成;此时再进行其它操作,就不会有问题了。

python操作sqlite3的几项问题分析的更多相关文章

  1. 《Python操作SQLite3数据库》快速上手教程

    为什么使用SQLite数据库? 对于非常简单的应用而言,使用文件作为持久化存储通常就足够了,但是大多数复杂的数据驱动的应用需要全功能的关系型数据库.SQLite的目标则是介于两者之间的中小系统.它有以 ...

  2. Python操作Mysql之基本操作

    pymysql python操作mysql依赖pymysql这个模块 下载安装 pip3 install pymysql 操作mysql python操作mysql的时候,是通过”游标”来进行操作的. ...

  3. Python开发【第十一篇】:Python操作MySQL

    本篇对于Python操作MySQL主要使用两种方式: 1.原生模块pymsql. 2.ORM框架SQLAchemy. pymsql pymsql是Python中操作MySQL的模块,其使用方法和MyS ...

  4. Flask:操作SQLite3(0.1)

    Windows 10家庭中文版,Python 3.6.4,Flask 1.0.2 本文介绍了第一次在Flask框架中操作SQLite3数据库的测试,参考了官网的文档Using SQLite 3 wit ...

  5. 孤荷凌寒自学python第四十四天Python操作 数据库之准备工作

     孤荷凌寒自学python第四十四天Python操作数据库之准备工作 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 今天非常激动地开始接触Python的数据库操作的学习了,数据库是系统化设计 ...

  6. Python操作MySQL[转]

    本篇对于Python操作MySQL主要使用两种方式: 1.原生模块pymsql. 2.ORM框架SQLAchemy. pymsql pymsql是Python中操作MySQL的模块,其使用方法和MyS ...

  7. Python操作SQLite数据库的方法详解

    Python操作SQLite数据库的方法详解 本文实例讲述了Python操作SQLite数据库的方法.分享给大家供大家参考,具体如下: SQLite简单介绍 SQLite数据库是一款非常小巧的嵌入式开 ...

  8. python——操作Redis

    在使用django的websocket的时候,发现web请求和其他当前的django进程的内存是不共享的,猜测django的机制可能是每来一个web请求,就开启一个进程去与web进行交互,一次来达到利 ...

  9. ofbiz进击 。 ofbiz 退货流程(包含获取可退货项流程分析 以及 取消退货项的过程分析)

    根据订单获取可退货项流程分析 退货的时候,调用 services_return.xml 中的获取可进行退货的退货项  getReturnableItems  ,该服务调用了Java类 org.ofbi ...

随机推荐

  1. (一)从设计的角度来看ADT(Java)

    <数据结构与抽象——Java语言描述>第一章学习笔记 感想:以前学数据结构关注于方法及实现,为了完成作业和手写代码,没有从设计层面考虑过,第一章设计一个bag ADT,借助于Java in ...

  2. String类——StringBuilder类的源码及内存分析(java)

    相同:底层均采用字符数组value来保存字符串 区别:String类的value数组有final 修饰,指向不可改,同时private 未提供修改value数组的方法.StringBuilder类的v ...

  3. PAT 1050 String Subtraction

    1050 String Subtraction (20 分)   Given two strings S​1​​ and S​2​​, S=S​1​​−S​2​​ is defined to be t ...

  4. C# 条件表达式max=(a>b)?a:b;含义

    a?b:c 这个是条件表达式,表示如果a为真,则表达式值为b,如果a为假,则表达式值为c条件表达式具体说明如下条件语句: if(a>b) max=a; else max=b; 可用条件表达式写为 ...

  5. lua中的逻辑运算符

    逻辑运算符也是3个,and,or,not,只是不是返回false和true,只有false和nil表示假,其他的都是真 and and使用短路运算,a and b,如果a为假,结果已经定了,返回a假, ...

  6. Express 路径请求及对应的获取路径形式

    req.query // GET /search?q=tobi+ferret req.query.q // => "tobi ferret" // GET /shoes?or ...

  7. Android Studio向项目添加C/C++原生代码教程

    说明:本文相当于官方文档的个人重新实现,官方文档链接:https://developer.android.com/studio/projects/add-native-code 向项目添加C/C++代 ...

  8. WebSphere静默安装教程(WAS6.1为例)

    1.安装WebSphere 解压守装包: tar -zxf was_soft_64-bit.tar.gz 进入解压出的WAS目录编缉responsefile.nd.txt,将对应选项修值改成以下模样( ...

  9. Android 编码规范

    1.文件编码:UTF-8 源文件编码格式为 UTF-8. 2.数组初始化:可写成块状结构 数组初始化可以写成块状结构,比如,下面的写法都是OK的: new int[] { 0, 1, 2, 3 } n ...

  10. List.contains()与自动拆箱

    最近项目引入sonarQube这种代码静态检查的东东,以前没有人力和精力review,现在只要扫描一下项目,就发现很多有趣的地方. 有这么一段代码: List<Long> list = L ...