多线程中的 SQLAlchemy scoped_session
SQLAlchemy in multithread scoped_session
我正在尝试在多线程环境中使用 SQLAlchemy,但遇到了奇怪的错误。情况是这样的:
线程 1 启动所有 SQLAlchemy 对象(引擎、模型、scoped_session 等)
线程 2 然后尝试使用 scoped_session 对象来查询数据库。不幸的是,从线程 2 中抛出错误。
我创建了一个简单的测试用例来说明我要完成的任务:
import sqlalchemy
from sqlalchemy import Column, Integer, String, Boolean, desc, asc, func
from sqlalchemy import create_engine
sqlEngine = create_engine('sqlite:///:memory:',echo=False)
from sqlalchemy.orm import sessionmaker, scoped_session
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class SimpleTable(Base):
__tablename__ = 'SimpleTable'
orderID = Column(Integer, primary_key=True)
field = Column(Integer)
def __repr__(self):
return "<Simple Table: %s>" % self.field
session_factory = sessionmaker(bind=sqlEngine)
Session = scoped_session(session_factory)
Base.metadata.create_all(sqlEngine)
for i in xrange(10):
var = SimpleTable(field=10)
Session.add(var)
Session.query(SimpleTable).all()
Session.commit()
from threading import Thread
class TestThread(Thread):
def run(self):
print "Running test thread..."
try:
print 'Grabbing data from thread:'+str(Session.query(SimpleTable).all())
except BaseException as e:
print e
print "Done running test thread..."
TestThread().start()
print 'Grabbing data outside thread:'+str(Session.query(SimpleTable).all())
这是带有错误消息的输出:
Running test thread...
(OperationalError) no such table: SimpleTable u'SELECT "SimpleTable"."orderID" AS "SimpleTable_orderID", "SimpleTable".field AS "SimpleTable_field" \nFROM "SimpleTable"' ()
Done running test thread...
Grabbing data outside thread:[<Simple Table: 10>, <Simple Table: 10>, <Simple Table: 10>, <Simple Table: 10>, <Simple Table: 10>, <Simple Table: 10>, <Simple Table: 10>, <Simple Table: 10>, <Simple Table: 10>, <Simple Table: 10>]
table 由于某种原因不存在。我已经阅读并重读了文档以及互联网上的多篇文章,似乎 scoped_session 确实存在上述情况。有人可以启发我吗?
我遇到过同样的情况。我怀疑 "in memory" 数据库不支持 scoped_session。当我切换到基于普通文件的数据库时,问题就消失了。
您可以使用 scoped_session 工厂,只要您手动注意将会话实例绑定到请求而不是直接绑定到线程。检查非必需的 scopefunc 参数。它应该采用一些可散列的对象。当使用具有可哈希请求的 Web 框架时,您可以将 id 直接作为值。如果不只是将其包装到可哈希对象中。
from my_web_framework import get_current_request, on_request_end
from sqlalchemy.orm import scoped_session, sessionmaker
Session = scoped_session(sessionmaker(bind=some_engine), scopefunc=get_current_request)
@on_request_end
def remove_session(req):
Session.remove()
请记住,必须在请求结束时手动销毁会话!您会在 using-custom-created-scopes
下找到更多信息
我正在尝试在多线程环境中使用 SQLAlchemy,但遇到了奇怪的错误。情况是这样的:
线程 1 启动所有 SQLAlchemy 对象(引擎、模型、scoped_session 等)
线程 2 然后尝试使用 scoped_session 对象来查询数据库。不幸的是,从线程 2 中抛出错误。
我创建了一个简单的测试用例来说明我要完成的任务:
import sqlalchemy
from sqlalchemy import Column, Integer, String, Boolean, desc, asc, func
from sqlalchemy import create_engine
sqlEngine = create_engine('sqlite:///:memory:',echo=False)
from sqlalchemy.orm import sessionmaker, scoped_session
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class SimpleTable(Base):
__tablename__ = 'SimpleTable'
orderID = Column(Integer, primary_key=True)
field = Column(Integer)
def __repr__(self):
return "<Simple Table: %s>" % self.field
session_factory = sessionmaker(bind=sqlEngine)
Session = scoped_session(session_factory)
Base.metadata.create_all(sqlEngine)
for i in xrange(10):
var = SimpleTable(field=10)
Session.add(var)
Session.query(SimpleTable).all()
Session.commit()
from threading import Thread
class TestThread(Thread):
def run(self):
print "Running test thread..."
try:
print 'Grabbing data from thread:'+str(Session.query(SimpleTable).all())
except BaseException as e:
print e
print "Done running test thread..."
TestThread().start()
print 'Grabbing data outside thread:'+str(Session.query(SimpleTable).all())
这是带有错误消息的输出:
Running test thread...
(OperationalError) no such table: SimpleTable u'SELECT "SimpleTable"."orderID" AS "SimpleTable_orderID", "SimpleTable".field AS "SimpleTable_field" \nFROM "SimpleTable"' ()
Done running test thread...
Grabbing data outside thread:[<Simple Table: 10>, <Simple Table: 10>, <Simple Table: 10>, <Simple Table: 10>, <Simple Table: 10>, <Simple Table: 10>, <Simple Table: 10>, <Simple Table: 10>, <Simple Table: 10>, <Simple Table: 10>]
table 由于某种原因不存在。我已经阅读并重读了文档以及互联网上的多篇文章,似乎 scoped_session 确实存在上述情况。有人可以启发我吗?
我遇到过同样的情况。我怀疑 "in memory" 数据库不支持 scoped_session。当我切换到基于普通文件的数据库时,问题就消失了。
您可以使用 scoped_session 工厂,只要您手动注意将会话实例绑定到请求而不是直接绑定到线程。检查非必需的 scopefunc 参数。它应该采用一些可散列的对象。当使用具有可哈希请求的 Web 框架时,您可以将 id 直接作为值。如果不只是将其包装到可哈希对象中。
from my_web_framework import get_current_request, on_request_end
from sqlalchemy.orm import scoped_session, sessionmaker
Session = scoped_session(sessionmaker(bind=some_engine), scopefunc=get_current_request)
@on_request_end
def remove_session(req):
Session.remove()
请记住,必须在请求结束时手动销毁会话!您会在 using-custom-created-scopes
下找到更多信息