我有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()
以下是我如何定义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
first()完成正常(需要大约4小时)并且我看到“打印到第二个函数”然后立即给我一个错误:
sqlalchemy.exc.OperationalError: (OperationalError) (2006,'MysqL server has gone away')
从阅读文档我认为分配session = DBSession会得到两个不同的会话实例,所以second()不会超时.我也试过玩pool_recycle,这似乎没有任何影响.在现实世界中,我不能将first()和second()分成2个脚本:second()必须在first()之后立即执行
最佳答案
assigning session=DBSession would get two different session instances
这根本不是真的. session = DBSession是一个局部变量赋值,你不能在Python中覆盖局部变量赋值(你可以覆盖实例成员赋值,但这是无关的).
另外需要注意的是,scoped_session默认情况下会产生一个线程局部范围的会话(即同一个线程中的所有代码都具有相同的会话).由于您在同一个线程中调用first()和second(),因此它们是同一个会话.
您可以做的一件事是使用常规(无范围)会话,只需手动管理会话范围并在两个函数中创建新会话.或者,您可以查看有关如何define custom session scope的文档.