我有一个使用"线程"模块的Python程序.每隔一秒,我的程序就会启动一个新的线程,从网络中获取一些数据,并将这些数据存储到我的硬盘中.我想使用sqlite3来存储这些结果,但我无法让它工作.问题似乎与以下几行有关:
conn = sqlite3.connect("mydatabase.db")
Run Code Online (Sandbox Code Playgroud)
以前我将所有结果存储在CSV文件中,并且没有任何这些文件锁定问题.希望这可以用sqlite实现.有任何想法吗?
Jer*_*ose 171
与流行的看法相反,较新版本的sqlite3 确实支持来自多个线程的访问.
这可以通过可选的关键字参数启用check_same_thread:
sqlite.connect(":memory:", check_same_thread=False)
Run Code Online (Sandbox Code Playgroud)
Evg*_*zin 40
您可以使用消费者 - 生产者模式.例如,您可以创建线程之间共享的队列.从Web获取数据的第一个线程将此数据排入共享队列.另一个拥有数据库连接的线程将队列中的数据从队列中取出并将其传递给数据库.
小智 16
在mail.python.org.pipermail.1239789
上找到以下内容我找到了解决方案.我不知道为什么python文档没有关于这个选项的单一词.所以我们必须在连接函数中添加一个新的关键字参数,我们将能够在不同的线程中创建游标.所以使用:
sqlite.connect(":memory:", check_same_thread = False)
Run Code Online (Sandbox Code Playgroud)
对我来说很完美.当然,从现在开始,我需要处理对数据库的安全多线程访问.无论如何,所有的尝试帮助.
Dus*_*tin 13
你根本不应该使用线程.对于扭曲而言,这是一项微不足道的任务,无论如何这可能会让你更进一步.
仅使用一个线程,并完成请求触发事件以进行写入.
twisted会为你安排调度,回调等等.它会将整个结果作为字符串传递给您,或者您可以通过流处理器运行它(我有一个Twitter API和一个friendfeed API,它们都会在调用结果仍在下载时向调用者发出事件).
根据您对数据的处理方式,您可以将完整的结果转储到sqlite中,完成后,将其煮熟并转储,或者在读取时将其煮熟并在最后转储.
我有一个非常简单的应用程序,它在github上做了一些你想要的东西.我称之为pfetch(并行获取).它按计划抓取各种页面,将结果流式传输到文件,并可选择在成功完成每个脚本后运行脚本.它也做了一些奇特的东西,如条件GET,但仍然可以成为你正在做的任何事情的良好基础.
nos*_*klo 12
切换到多处理.它更好,扩展性好,可以通过使用多个CPU来超越使用多个内核,并且接口与使用python线程模块相同.
或者,正如Ali建议的那样,只需使用SQLAlchemy的线程池机制.它将自动为您处理所有事情并具有许多额外功能,仅引用其中一些:
或者,如果你像我一样懒惰,你可以使用SQLAlchemy.它将为您处理线程(使用线程本地和一些连接池),它的工作方式甚至可配置.
如果/当您意识到/决定使用Sqlite进行任何并发应用程序将是一场灾难时,您将不必更改代码以使用MySQL,Postgres或其他任何东西.你可以切换.