use*_*084 5 python mysql sqlalchemy
我有2个需要执行的函数,第一个需要大约4个小时才能执行.两者都使用SQLAlchemy:
def first():
session = DBSession
rows = session.query(Mytable).order_by(Mytable.col1.desc())[:150]
for i,row in enumerate(rows):
time.sleep(100)
print i, row.accession
def second():
print "going onto second function"
session = DBSession
new_row = session.query(Anothertable).order_by(Anothertable.col1.desc()).first()
print 'New Row: ', new_row.accession
first()
second()
Run Code Online (Sandbox Code Playgroud)
以下是我如何定义DBSession:
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy import create_engine
engine = create_engine('mysql://blah:blah@blah/blahblah',echo=False,pool_recycle=3600*12)
DBSession = scoped_session(sessionmaker(autocommit=False, autoflush=False, bind=engine))
Base = declarative_base()
Base.metadata.bind = engine
Run Code Online (Sandbox Code Playgroud)
first()完成正常(需要大约4小时)并且我看到"打印到第二个函数"然后立即给我一个错误:
sqlalchemy.exc.OperationalError: (OperationalError) (2006, 'MySQL server has gone away')
Run Code Online (Sandbox Code Playgroud)
从阅读文档我认为分配session = DBSession会得到两个不同的会话实例,所以second()不会超时.我也试过玩pool_recycle,这似乎没有任何影响.在现实世界中,我不能将first()和second()分成2个脚本:second()必须在first()之后立即执行
分配 session=DBSession 将获得两个不同的会话实例
这根本不是真的。session = DBSession是局部变量赋值,并且您不能覆盖 Python 中的局部变量赋值(您可以覆盖实例成员赋值,但这是不相关的)。
另一件需要注意的事情是,scoped_session 默认情况下会生成一个线程本地作用域会话(即同一线程中的所有代码都具有相同的会话)。由于您在同一线程中调用first()和second(),因此它们是同一个会话。
您可以做的一件事是使用常规(无范围)会话,只需手动管理会话范围并在两个函数中创建一个新会话。或者,您可以查看有关如何定义自定义会话范围的文档。