FastAPI 在使用同步函数时跨线程共享 SQLAlchemy 会话
FastAPI sharing SQLAlchemy session across threads when using synchronous functions
关于正常 def
路径操作函数、依赖项和 SQLAlchemy 的菜鸟问题。引用这里的例子:https://fastapi.tiangolo.com/tutorial/sql-databases/#create-a-dependency, where the db sessions is created in get_db()
(synchronous) and used in create_user()
(synchronous). According to https://fastapi.tiangolo.com/async/#very-technical-details,同步依赖和路径操作函数是在一个线程池中执行的,所以这是否意味着同一个数据库会话对象在2个不同的线程之间有效共享(假设它不是同一个线程重新获取-跨依赖和路径操作功能使用)?这会不会有问题,因为 SQLAlchemy 会话不是线程安全的?
我可能完全误解了它的工作原理,因此非常感谢任何澄清。
谢谢!
编辑:在进一步考虑之后,我认为这应该没问题,因为会话是按顺序访问的(不是同时访问的),即使它可能由两个不同的线程访问。但我假设像下面这样使用 session
会有问题吗?
async def func(s: Session):
loop = asyncio.get_running_loop()
await loop.run_in_executor(None, some_func, s)
await loop.run_in_executor(None, some_other_func, s)
...
是的会话对象不是 thread-safe,但在 SQLAlchemy 中你实际上有多个连接,因为 SQLAlchemy 有一个连接池系统 default 所以你定义的每个其他 SessionLocal 都有自己的连接
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
所以,没有共享连接,所有东西都是分开的,而且 SessionLocal 在请求后立即关闭。所以这不是 thread-safe,但我认为这不会有问题。
假设您有一个端点,它同时收到 2 个请求,因此在这种情况下,不同的连接将响应您的请求。即使它不是并发的,它的行为也像与 Pooling 并发一样。
关于正常 def
路径操作函数、依赖项和 SQLAlchemy 的菜鸟问题。引用这里的例子:https://fastapi.tiangolo.com/tutorial/sql-databases/#create-a-dependency, where the db sessions is created in get_db()
(synchronous) and used in create_user()
(synchronous). According to https://fastapi.tiangolo.com/async/#very-technical-details,同步依赖和路径操作函数是在一个线程池中执行的,所以这是否意味着同一个数据库会话对象在2个不同的线程之间有效共享(假设它不是同一个线程重新获取-跨依赖和路径操作功能使用)?这会不会有问题,因为 SQLAlchemy 会话不是线程安全的?
我可能完全误解了它的工作原理,因此非常感谢任何澄清。
谢谢!
编辑:在进一步考虑之后,我认为这应该没问题,因为会话是按顺序访问的(不是同时访问的),即使它可能由两个不同的线程访问。但我假设像下面这样使用 session
会有问题吗?
async def func(s: Session):
loop = asyncio.get_running_loop()
await loop.run_in_executor(None, some_func, s)
await loop.run_in_executor(None, some_other_func, s)
...
是的会话对象不是 thread-safe,但在 SQLAlchemy 中你实际上有多个连接,因为 SQLAlchemy 有一个连接池系统 default 所以你定义的每个其他 SessionLocal 都有自己的连接
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
所以,没有共享连接,所有东西都是分开的,而且 SessionLocal 在请求后立即关闭。所以这不是 thread-safe,但我认为这不会有问题。
假设您有一个端点,它同时收到 2 个请求,因此在这种情况下,不同的连接将响应您的请求。即使它不是并发的,它的行为也像与 Pooling 并发一样。