我有一个带有原始SQLalchemy的Flask应用程序。应用程序旨在在公司内部使用,以便更轻松地使用MySQL保存测量数据
在一个页面上,我有一张表格,其中包含用于测量的所有设备以及用于添加,删除或修改测量设备的表格。
问题在于,当我在数据库中输入新设备时,页面会自动刷新以从DB中获取新数据,有时会显示新设备,有时则不会刷新页面。换句话说,即使行在数据库中可见,表中添加的行也会出现并消失。当我尝试从数据库中删除设备时也是如此。有时会显示该行,有时在刷新页面时不会从DB中删除行。 对于与此类似的所有示例(添加,删除和修改数据),都会出现同样的问题。
Bellow是表格模型的代码:
class DvDevice(Base):
__tablename__ = "dvdevice"
id = Column("device_id", Integer, primary_key=True, autoincrement=True)
name = Column("device_name", String(50), nullable=True)
code = Column("device_code", String(10), nullable=True, unique=True)
hw_ver = Column("hw_ver", String(10), nullable=True)
fw_ver = Column("fw_ver", String(10), nullable=True)
sw_ver = Column("sw_ver", String(10), nullable=True)
这是从表中插入/删除数据的代码。
#Insertion
device = DvDevice()
device.code = self.device_code
device.name = self.device_name
device.hw_ver = self.hw_ver
device.fw_ver = self.fw_ver
device.sw_ver = self.sw_ver
ses.add(device)
ses.commit()
ses.expire_all() #Should this be here?
# Deletion
ses.query(DvDevice).filter_by(id=self.device_id).delete()
ses.commit()
ses.expire_all() # Should this be here?
我已经从堆栈上的一些帖子中读到了在models.py中包含以下装饰器函数
@app.teardown_appcontext
def shutdown_session(exception=None):
ses.expire_all() #ses being database session object.
我尝试了这个,它仍然无法正常工作。我应该把装饰器功能放在其他地方吗?
我尝试的第二件事是在所有提交之后放置ses.expire_all()
它仍然无效。
我该怎么做才能防止这种情况发生?
from sqlalchemy import create_engine, update
from sqlalchemy.orm import sessionmaker
from sqlalchemy.pool import NullPool
from config import MYSQLCONNECT
engine = create_engine(MYSQLCONNECT)
Session = sessionmaker(bind=engine)
session = Session()
答案 0 :(得分:1)
我使用http://docs.sqlalchemy.org/en/latest/orm/session_basics.html#when-do-i-construct-a-session-when-do-i-commit-it-and-when-do-i-close-it中的以下函数解决了这个问题:
from contextlib import contextmanager
@contextmanager
def session_scope():
"""Provide a transactional scope around a series of operations."""
session = Session()
try:
yield session
session.commit()
except:
session.rollback()
raise
finally:
session.close()
with session_scope() as session:
... # code that uses session
问题是我在beggining中创建了会话对象,然后从未关闭它。