我需要在多个页面请求上运行相同的确切查询。 第一页呈现项目,第二页将项目导出为excel。
直接在会话上存储查询失败,因为BaseQuery
不是JSON可序列化的:
session['previous_query'] = SomeModel.query
下一个选项是将查询存储为字符串:
session['previous_query'] = str(SomeModel.query)
这有效但我现在需要运行session.execute:
db.session.execute(session['previous_query'])
这并没有给我ORM对象,而是没有关系的简单dicts。
最后我只能存储id,但这需要我多次在两端运行查询,并且不会保留我需要的顺序。
有什么建议吗?
答案 0 :(得分:4)
您可以使用SQLAlchemy Serializer扩展序列化查询:
from sqlalchemy.ext import serializer
session['previous_query'] = serializer.dumps(SomeModel.query, -1)
然后使用以下命令重新构建查询:
query = serializer.loads(session['previous_query'], db.metadata, db.session)
objects = query.all()
其中db
是您的Flask-SQLAlchemy集成对象。
在幕后,它使用pickle
模块,但酸洗已经过定制,更加紧凑,省略了会话和引擎参考;使用serializer.loads()
加载序列化数据时会再次加载这些数据。
为了在Python 2上工作,您需要设置协议版本(第二个参数为serializer.dumps()
),因为seralization不能使用默认协议版本0.选择版本1或2而不是,或使用-1
选择Python安装支持的最高版本。
因为它使用泡菜,所以要小心从不受信任的来源加载泡菜; Flask会话是防篡改的,因为它是加密签名的,但如果攻击者能够获得您的服务器端密码,那么攻击者可以通过向您发送精心设计的serializer.loads()
的pickle来接管您的流程。