SQLalchemy returns SELECT 命令的不同结果 (query.all)
Sqlalchemy returns different results of the SELECT command (query.all)
我有网络服务器(512 RAM):
FLASK + SQLAlchemy (SQLite) -> uWSGI -> Nginx
问题:Sqlalchemy returns SELECT 命令 (query.all) 的不同结果。
示例:
- 在数据库中添加了一些记录。
- 我重新加载页面:新记录没有返回(但旧记录返回)。
- 重新加载页面:返回所有记录。太好了。
- 重新加载页面:再次没有返回新记录。 (但旧的返回)。
只要我不重启 Flask 应用程序,就会发生这种情况。
代码如下:
DECLARATIVE_BASE = declarative_base()
engine = create_engine('sqlite:///database.db')
Session = sessionmaker(bind=engine)
session = Session()
class Order(DECLARATIVE_BASE):
__tablename__ = 'orders'
__table_args__ = (
{'mysql_engine': 'InnoDB', 'sqlite_autoincrement': True, 'mysql_charset': 'utf8'}
)
id = Column(INTEGER, autoincrement=True, primary_key=True, nullable=False) # pylint: disable=invalid-name
name = Column(TEXT, nullable=False)
address = Column(TEXT)
phone = Column(TEXT, nullable=False)
email = Column(TEXT)
comment = Column(TEXT)
totalPrice = Column(DECIMAL(asdecimal=False))
orderItems = relationship(Orderitem)
time = Column(TEXT, default=time.strftime("%H:%m %d.%m.%y"))
def __repr__(self):
return self.__str__()
def __str__(self):
return "<Order(%s)>" % self.__dict__
@app.route('/api/orders', methods=['GET'])
def getAllOrders():
allOrders = session.query(Order).all()
return json.dumps(allOrders, cls=new_alchemy_encoder(False, ['orderItems', 'product']), check_circular=False, ensure_ascii=False) #ensure_ascii=False -- for rigth out cyrlic;
每个 Worker 有一个 SQLAlchemy 会话,并且可能使用 2 个 Worker 和 uwsgi。 SQLAlchemy 缓存每个会话的结果,因此 worker 1 的会话 returns 新结果,因为您已经添加了该 worker 的记录,但是 worker 2 的会话没有更新并且 returns 只有旧记录。
解决方案:不要创建全局会话,而是为每个请求创建一个新会话。
@app.route('/api/orders', methods=['GET'])
def getAllOrders():
session = Session()
allOrders = session.query(Order).all()
return json.dumps(allOrders, cls=new_alchemy_encoder(False, ['orderItems', 'product']), check_circular=False, ensure_ascii=False) #ensure_ascii=False -- for rigth out cyrlic;
这应该有所帮助。 SQLAlchemy 会话未正确关闭!
@app.teardown_appcontext
def shutdown_session(exception=None):
Session.remove()
我有网络服务器(512 RAM): FLASK + SQLAlchemy (SQLite) -> uWSGI -> Nginx
问题:Sqlalchemy returns SELECT 命令 (query.all) 的不同结果。
示例:
- 在数据库中添加了一些记录。
- 我重新加载页面:新记录没有返回(但旧记录返回)。
- 重新加载页面:返回所有记录。太好了。
- 重新加载页面:再次没有返回新记录。 (但旧的返回)。
只要我不重启 Flask 应用程序,就会发生这种情况。
代码如下:
DECLARATIVE_BASE = declarative_base()
engine = create_engine('sqlite:///database.db')
Session = sessionmaker(bind=engine)
session = Session()
class Order(DECLARATIVE_BASE):
__tablename__ = 'orders'
__table_args__ = (
{'mysql_engine': 'InnoDB', 'sqlite_autoincrement': True, 'mysql_charset': 'utf8'}
)
id = Column(INTEGER, autoincrement=True, primary_key=True, nullable=False) # pylint: disable=invalid-name
name = Column(TEXT, nullable=False)
address = Column(TEXT)
phone = Column(TEXT, nullable=False)
email = Column(TEXT)
comment = Column(TEXT)
totalPrice = Column(DECIMAL(asdecimal=False))
orderItems = relationship(Orderitem)
time = Column(TEXT, default=time.strftime("%H:%m %d.%m.%y"))
def __repr__(self):
return self.__str__()
def __str__(self):
return "<Order(%s)>" % self.__dict__
@app.route('/api/orders', methods=['GET'])
def getAllOrders():
allOrders = session.query(Order).all()
return json.dumps(allOrders, cls=new_alchemy_encoder(False, ['orderItems', 'product']), check_circular=False, ensure_ascii=False) #ensure_ascii=False -- for rigth out cyrlic;
每个 Worker 有一个 SQLAlchemy 会话,并且可能使用 2 个 Worker 和 uwsgi。 SQLAlchemy 缓存每个会话的结果,因此 worker 1 的会话 returns 新结果,因为您已经添加了该 worker 的记录,但是 worker 2 的会话没有更新并且 returns 只有旧记录。
解决方案:不要创建全局会话,而是为每个请求创建一个新会话。
@app.route('/api/orders', methods=['GET'])
def getAllOrders():
session = Session()
allOrders = session.query(Order).all()
return json.dumps(allOrders, cls=new_alchemy_encoder(False, ['orderItems', 'product']), check_circular=False, ensure_ascii=False) #ensure_ascii=False -- for rigth out cyrlic;
这应该有所帮助。 SQLAlchemy 会话未正确关闭!
@app.teardown_appcontext
def shutdown_session(exception=None):
Session.remove()