SQLite3和多处理

时间:2011-08-07 00:05:36

标签: python sqlite multiprocessing

我注意到当我在多处理环境中使用它时,sqlite3确实不具备能力,也不可靠。每个进程都会尝试将一些数据写入同一个数据库,以便多个线程使用连接。我尝试使用check_same_thread = False选项,但插入次数非常随机:有时它包含所有内容,有时不包括。我应该只并行处理函数的一部分(从Web获取数据),将它们的输出堆叠到一个列表中并将它们一起放入表中,还是有一种可靠的方法来处理与sqlite的多连接?

4 个答案:

答案 0 :(得分:7)

首先,多处理(多个进程)和多线程(一个进程中的多个线程)之间存在差异。

这似乎是你在谈论多线程。在多线程环境中使用SQLite时,您应该注意几点需要注意的事项。 SQLite documentation提及以下内容:

  
      
  • 不要同时使用相同的数据库连接   一个帖子。
  •   
  • 在某些操作系统上,应该是数据库连接   始终在最初创建它的同一个线程中使用。
  •   

有关详细信息,请参阅此处:Is SQLite thread-safe?

答案 1 :(得分:3)

我实际上只是在做一些非常相似的事情:

  • 多个流程(对我来说是一个4到32个工人的处理池)
  • 每个流程工作者都会做一些包括获取信息的内容 来自网络(对我的Alchemy API的调用)
  • 每个进程都会打开自己的sqlite3连接,所有这些都连接到一个文件,每个进程都是 在将下一个任务从堆栈中移除之前,进程会添加一个条目

起初我以为我遇到了和你一样的问题,然后我将其追溯到从网络上检索信息的重叠和冲突问题。因为我在那里,我对sqlite和多处理进行了一些酷刑测试,发现我可以运行许多进程工作者,所有连接和添加到相同的sqlite文件而没有协调,当我只是输入测试数据时它是坚如磐石。

现在,我正在查看您的短语"(从网络上获取数据)" - 也许您可以尝试用一些虚拟数据替换数据获取,以确保它确实是sqlite3连接导致您出现问题。至少在我测试的情况下(现在在另一个窗口中运行)我发现多个进程都可以通过自己的连接添加而没有问题但是你的描述完全符合我在两个进程互相踩的时候遇到的问题在访问Web API时(实际上非​​常奇怪的错误)有时候没有获得预期的数据,这当然会在数据库中留下一个空槽。我最终的解决方案是在每个worker中检测到这个失败,并在它发生时重试web API调用(可能更优雅,但这是个人黑客攻击)。

如果这不适用于您的案例,我很道歉,如果没有代码,很难知道您面临的是什么,但说明让我想知道您是否可以扩大您的考虑范围。

答案 2 :(得分:0)

如果我必须使用SQLITE构建一个类似你描述的系统,那么我首先要编写一个异步服务器(使用asynchat模块)来处理所有SQLITE数据库访问,然后我会写其他进程来使用该服务器。当只有一个进程直接访问db文件时,它可以强制执行严格的查询序列,这样就不会有两个进程踩到彼此脚趾的危险。它也比不断打开和关闭数据库更快。

事实上,我也会尽量避免维护会话,换句话说,我会尝试编写所有其他进程,以便每个数据库事务都是独立的。至少这意味着允许事务包含一个SQL语句列表,而不仅仅是一个,它甚至可能需要一些if then功能,以便您可以选择一条记录,检查一个字段是否等于X,以及只有这样,UPDATE那个字段。如果您的现有应用程序在每次交易后关闭数据库,那么您无需担心会话。

您可以使用类似nosqlite http://code.google.com/p/nosqlite/

的内容

答案 3 :(得分:0)

  

sqlitedict:围绕Python的sqlite3数据库的轻量级包装器,具有类似dict的接口和多线程访问支持。