我在我的python命令行应用中使用SQLAlchemy
。该应用程序基本上是读取一组URL并根据数据插入到postgreql数据库中。
在大约相同数量的插入(给予或采取一些)后,整个应用程序冻结。
看过python sqlalchemy + postgresql program freezes我假设我对SQLAlchemy
Session
做错了(虽然我没有使用drop_all()
,这似乎是导致问题)。我尝试了几件事,但到目前为止他们没有任何影响。
欢迎任何提示或帮助。如果我将SQLAlchemy
集成到我的应用程序中是不正确的,那么也欢迎指向正确行为的好例子。
我的代码如下:
设置sql炼金术基础:
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
创建会话信息并将其附加到Base
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
engine = create_engine("sqlite:///myapp.db")
db_session = scoped_session(sessionmaker(bind=engine))
Base.query = db_session.query_property()
Base.scoped_db_session = db_session
从Base创建我的模型并使用会话
class Person(Base):
def store(self):
if self.is_new():
self.scoped_db_session.add(self)
self.scoped_db_session.commit()
如果我创建了Person
类型的足够对象并调用store()
,那么该应用最终会冻结。
答案 0 :(得分:0)
管理解决问题。事实证明我的实施是专门针对不要这样做的列表(参见http://docs.sqlalchemy.org/en/latest/orm/session_basics.html#session-frequently-asked-questions 例如,不要这样做)和我没有正确管理会话
为了解决我的问题,我将会话从模型中移到了一个单独的类中,所以不要像以下那样调用:
mymodel.store()
我现在有:
db.current_session.store(mymodel)
其中db是我的自定义DBContext
的实例,如下所示:
from contextlib import contextmanager
from sqlalchemy.orm import scoped_session, sessionmaker
class DbContext(object):
def __init__(self, engine, session=None):
self._engine = engine
self._session = session or scoped_session(sessionmaker(autocommit=False, autoflush=False, bind=self._engine))
self.query = self._session.query_property()
self.current_session = None
def start_session(self):
self.current_session = self._session()
def end_session(self):
if self.current_session:
self.current_session.commit()
self.current_session.close()
self.current_session = None
@contextmanager
def new_session(self):
try:
self.start_session()
yield
finally:
self.end_session()
如果要存储一个或多个模型对象,请调用DBContext.start_session()
以启动干净会话。当您最终想要提交时,请致电DBContext.end_session()
。