Sqlite3错误:Recursive use of cursors not allowed 的解决方案
感悟】
写完这篇日志后,有调了一段时间程序,又有了一点心得分享下:
一)爬稳定的数(dong)据(xi)最好存储下来,特别是数据库在国外的那种,下载时间成本太高昂了,存起来再处理,会节约很多时间;
二)对于python使用多线程写数据到sqlite数据库的做法绝对是浪费感情,是扯淡的行为,一个词叫“大材小用”,单线程足够了。
三)写数据到数据库中commit的次数最好减少,可以10000条insert后commit,当然这取决于事务本身和其他因素,我这里可以提升一倍的速度。
四)回到爬的数据上,文本形式存储对于散户使用是最优的,处理速度快,格式定义好,正则等功能完胜sqlite。
【问题情境】
最近手闲,想写一个简单的批量下载网页的python工具。当然爬虫的轻量级框架scrapy以前用过,还不错。因为这次需求很简单,就直接人肉搞了。结果各种问题就出来了。
其中的思路是,多线程数据库存储这些网页,也方便之后数据处理。但是跑多线程时,脚本经常死掉。开了50个线程,基本出现的错误提示就是"Recursive use of cursors not allowed".
【问题分析】
数据库跑多线程的故事吧,一般都是事务没提交无法保证原子性的问题。问题解决方案可直接看下面的【问题解决】部分。
检查了第一遍:
问题1:发现有个查询语句select没有提交,commit了一下。
分析1:这里感觉没有什么问题,因为查询没有改变数据库所以不提交也一样。
跑一遍:
似乎错误提示少了一些。此时,我insert数据的sleep时间是1sec.试了几遍,还是中途崩掉。
检查第二遍:
问题2:缩短insert的sleep时间,问题更严重了。很快姐崩了。
分析2:应该是insert频繁导致的sql语句冲突概率增加。总感觉这里有问题,就差了下资料,果然是sqlite3多线程的时候有猫腻。于是,在每个提交的位置都增加了线程锁,增强同步效果。
跑了一遍:
错误提示"Recursive use of cursors not allowed"没有再出现。
【解决方案】
加锁,提交。
lock = threading.Lock()
def Func(host,cursor,db):
try:
lock.acquire(True)
res = cursor.execute('''...''',(host,))
# do something
finally:
lock.release()
【其他】
python的sqlite3使用多线程的参数check_same_thread是需要的:
self.conn = sqlite3.connect(dbname, check_same_thread=False)
版权声明:本文为CSDN博主「counsellor」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/counsellor/article/details/43715007
Sqlite3错误:Recursive use of cursors not allowed 的解决方案的更多相关文章
- 基于Windows下处理Java错误:编码GBK的不可映射字符的解决方案
基于Windows下处理Java错误:编码GBK的不可映射字符的解决方案 最近在研究Java,涉及命令行编译,使用notepad++编辑器,然后使用javac编译: 之前的几个文件没有中文的内容,都没 ...
- Visual studio 中编译错误SQL71006: Only one statement is allowed per batch. A batch separator, such as 'GO', might be required between statements.
把写好的sql脚本,并在mssqlmanager里面编译成功的存储过程脚本复制到vs项目下,出现错误信息如下:SQL71006: Only one statement is allowed per b ...
- 【c++错误】类的语法错误 error c2533:constructors not allowed a return type(构造函数不允许返回一个类型)
今天编写类的程序的时候不小心把类后的分号忘写了,就出现上面的错误提示. 顺便复习下类的正确格式: class 类名 { public: //习惯上将公有类型放在前面,便于阅读 ……(外部接口) pro ...
- 解决Gearman 报sqlite3错误
删除了系统原带的sqlite3 ,到官网上下一个源码,重新编译安装sqlite3. 如:把sqlite3安装到 /usr/local/sqlite3tar zxf sqlite3.xxxx.tar.g ...
- Hive错误:User root is not allowed to impersonate anonymous
修改hadoop 配置文件 etc/hadoop/core-site.xml,加入如下配置项: <property> <name>hadoop.proxyuser.root.h ...
- spring整合之后运行报什么只读错误。Write operations are not allowed in read-only mode (FlushMode.MANUAL): Turn your Session into FlushMode.COMMIT/AUTO or remove 'readOnly' marker from transaction definition.
解决办法, 再大dao的实现类上添加注解: @Transactional(readOnly = false ) 不让它只读就行了
- iOS上传应用过程中出现的错误"images contain alpha channels or transparencies"以及解决方案
如何取消图片透明度 本文永久地址为 http://www.cnblogs.com/ChenYilong/p/3989954.html,转载请注明出处. 当你试图通过<预览>进行" ...
- MySQL报错:Packets larger than max_allowed_packet are not allowed 的解决方案
在导大容量数据特别是CLOB数据时,可能会出现异常:“Packets larger than max_allowed_packet are not allowed”. 这是由于MySQL数据库有一个系 ...
- 引入第三方库错误Undefined symbols for architecture i386: _OBJC_CLASS_$的解决方案
引起标题上所导致的错误是因为你的第三方库没有放入到Compile Sources里面去. 需要到你项目的Targets>>Build Phases>>Compile Sourc ...
随机推荐
- NIO总结-----Buffer
Java NIO中的Buffer用于和NIO通道进行交互.如你所知,数据是从通道读入缓冲区,从缓冲区写入到通道中的. 缓冲区本质上是一块可以写入数据,然后可以从中读取数据的内存.这块内存被包装成NIO ...
- HTML练习一
效果图 动态图 html代码 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> ...
- http GET 和 POST 请求的优缺点和误区
(1)post更安全(不会作为url的一部分,不会被缓存.保存在服务器日志.以及浏览器浏览记录中) (2)post发送的数据更大(get有url长度限制) (3)post能发送更多的数据类型(get只 ...
- NET如何使用ELinq-实现增删改查
1 通过对ELinq主页的参考和学习,以及在项目中(wpf项目中用到的)中应用,ORM框架中的ELinq确实非常的强大,特此以建立wpf项目为例子来总结下如何在项目中应用ELinq,要想使用这个框架首 ...
- ZPL语言完成条形码的打印
近期因为项目的需求,需要使用到打印机来打印业务相关的条形码和其他信息,由于之前有操作其它打印机的经验,Leader就安排我来做这个了(凑哦,这能说我是懵逼的么).于是就开始了我的探索之旅啦,不对,是踩 ...
- vue常用知识点
vue中图片路径写法 <img :src="avatorSrc" alt=""> <img :src="avatorSrc2&quo ...
- Oracle笔记(十) 约束
表虽然建立完成了,但是表中的数据是否合法并不能有所检查,而如果要想针对于表中的数据做一些过滤的话,则可以通过约束完成,约束的主要功能是保证表中的数据合法性,按照约束的分类,一共有五种约束:非空约束.唯 ...
- 树的总结(遍历,BST,AVL原型,堆,练习题)
目录 树 一.抽象数据类型 二.二叉树的性质 三.二叉树的遍历 三.活用树的遍历 四.BST树 五.AVL树 六.BST树和AVL树练习 七.堆 树 @ 一.抽象数据类型 1.顺序存储 使用数组存储 ...
- C#的Lazy与LazyInitializer
class Program { static void Main(string[] args) { //初始化 Lazy 类的新实例 //当延迟初始化发生时,将使用指定的初始化函数和初始化模式 // ...
- 关于WebAssembly
一.WebAssembly是什么? WebAssembly(缩写为Wasm)是基于堆栈的虚拟机的二进制指令格式.Wasm被设计为一个可移植的目标,用于编译C / C ++ / Rust等高级语言,支持 ...