简体   繁体   English

如何通过 sqlalchemy 跨多个(衍生)python 进程使用 sqlite

[英]How to use sqlite across multiple (spawned) python processes via sqlalchemy

I have a file called db.py with the following code:我有一个名为 db.py 的文件,其中包含以下代码:

from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker


engine = create_engine('sqlite:///my_db.sqlite')
session = scoped_session(sessionmaker(bind=engine,autoflush=True))

I am trying to import this file in various subprocesses started using a spawn context (potentially important, since various fixes that worked for fork don't seem to work for spawn )我正在尝试在使用spawn上下文开始的各种子进程中导入此文件(可能很重要,因为适用于fork的各种修复似乎不适用于spawn

The import statement is something like:导入语句类似于:

from db import session

and then I use this session ad libitum without worrying about concurrency, assuming SQLite's internal locking mechanism will order transactions as to avoid concurrency error, I don't really care about transaction order.然后我随意使用这个session而不担心并发,假设SQLite的内部锁定机制将对事务进行排序以避免并发错误,我并不关心事务顺序。

This seems to result in errors like the following: sqlite3.ProgrammingError: SQLite objects created in a thread can only be used in that same thread. The object was created in thread id 139813508335360 and this is thread id 139818279995200.这似乎会导致如下错误: sqlite3.ProgrammingError: SQLite objects created in a thread can only be used in that same thread. The object was created in thread id 139813508335360 and this is thread id 139818279995200. sqlite3.ProgrammingError: SQLite objects created in a thread can only be used in that same thread. The object was created in thread id 139813508335360 and this is thread id 139818279995200.

Mind you, this doesn't directly seem to affect my program, every transaction goes through just fine, but I am still worried about what's causing this.请注意,这似乎并没有直接影响我的程序,每笔交易都进行得很好,但我仍然担心是什么原因造成的。

My understanding was that scoped_session was thread-local, so I could import it however I want without issues.我的理解是scoped_session是线程本地的,所以我可以随意导入它而不会出现问题。 Furthermore, my assumption was that sqlalchemy will always handle the closing of connections and that sqllite will handle ordering (ie make a session wait for another seesion to end until it can do any transaction).此外,我的假设是 sqlalchemy 将始终处理连接的关闭,sqllite 将处理排序(即,使 session 等待另一个视觉结束,直到它可以执行任何事务)。

Obviously one of these assumptions is wrong, or I am misunderstanding something basic about the mechanism here, but I can't quite figure out what.显然,其中一个假设是错误的,或者我误解了这里机制的一些基本内容,但我不太清楚是什么。 Any suggestions would be useful.任何建议都会很有用。

The problem isn't about thread-local sessions, it's that the original connection object is in a different thread to those sessions.问题不在于线程本地会话,而在于原始连接 object 与这些会话位于不同的线程中。 SQLite disables using a connection across different threads by default. SQLite 默认禁用跨不同线程的连接。

The simplest answer to your question is to turn off sqlite's same thread checking .您问题的最简单答案是关闭 sqlite 的 相同线程检查 In SQLAlchemy you can achieve this by specifying it as part of your database URL:在 SQLAlchemy 中,您可以通过将其指定为数据库 URL 的一部分来实现此目的:

engine = create_engine('sqlite:///my_db.sqlite?check_same_thread=False')

I'm guessing that will do away with the errors, at least.我猜这至少会消除错误。

Depending on what you're doing, this may still be dangerous - if you're ensuring your transactions are serialised (that is, one after the other, never overlapping or simultaneous) then you're probably fine.根据您正在做的事情,这可能仍然很危险 - 如果您确保您的交易是序列化的(即,一个接一个,从不重叠或同时),那么您可能没问题。 If you can't guarantee that then you're risking data corruption, in which case you should consider a) using a database backend that can handle concurrent writes, or b) creating an intermediary app or service that solely manages sqlite reads and writes and that your other apps can communicate with.如果您不能保证,那么您将面临数据损坏的风险,在这种情况下,您应该考虑 a) 使用可以处理并发写入的数据库后端,或 b) 创建一个中间应用程序或服务,该应用程序或服务仅管理 sqlite 读写和您的其他应用程序可以与之通信。 That latter option sounds fun but be warned you may end up reinventing the wheel when you're better off just spinning up a Postgres container or something.后一种选择听起来很有趣,但请注意,当你最好只是旋转一个 Postgres 容器或其他东西时,你最终可能会重新发明轮子。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 python中跨多个进程的同步 - synchronization across multiple processes in python 跨衍生进程复制“multiprocessing.Queue” - Duplicating a `multiprocessing.Queue` across spawned processes 如何通过 SQLAlchemy 部分覆盖 python 中的 sqlite3 db 中的 blob? - How to partially overwrite blob in an sqlite3 db in python via SQLAlchemy? 如何跨多个进程在Python类中创建唯一ID - How to create a unique ID in a Python Class across multiple processes 如何将新的 JVM 附加到生成的 Python 进程? - How do I attach new JVMs to spawned Python Processes? 如何使用Python在多个进程中运行pycuda - How to use Python to run pycuda in multiple processes 无法在 Python 中的多个对象之间使用相同的 SQLite 连接 - Unable to use same SQLite connection across multiple objects in Python 如何使用 Python 的 concurrent.futures 跨多个进程对任务进行排队,每个进程都有自己的线程池? - How can I use Python's concurrent.futures to queue tasks across multiple processes each with their own thread pool? 在多个进程中使用 Python flock() - Using Python flock() across multiple processes 在多个独立进程中使用Python RLock - Using Python RLocks across multiple independent processes
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM