我有一个jquery脚本向烧瓶服务器上的路由发送ajax post请求。 我希望路由计算SQLAlchemy选择查询并将结果返回到jquery脚本。
问题在于我无法找到一种简单而通用的方法将sqlalchemy查询结果直接转换为json,或javascript可理解的其他格式。
所以目前我必须为我的所有sqlalchemy类编程一个长的专用“serialize()”函数来强制str()像datetime这样的危险类型,然后jsonify它。
但我希望只有一个函数可以直接转换sqlalchemy请求结果的一行,而不是每个sqlalchemy类的专用函数。
以下是我现在正在做的一个例子:
VIEWS中的路线:
@app.route('/ajax/programme', methods=['POST'])
def retrieve_programme():
if request.method == 'POST':
shows_list = Shows.query.all()
result = []
for i in shows_list:
result.append(i.serialize(['id', 'date', 'title']))
return json.dumps(result)
我的SHOWS模型,带有序列化功能:
class Shows(db.Model):
__tablename__ = "shows"
id = Column(db.Integer, ForeignKey("programmation.id"), primary_key=True)
date = Column(db.DATETIME)
title = Column(db.VARCHAR(50))
short_description = Column(db.VARCHAR(200))
type = Column(db.VARCHAR(20))
background_image = Column(MEDIUMBLOB)
content = Column(LONGTEXT)
def serialize(self, whatTo):
result = {}
if 'id' in whatTo:
result['id'] = self.id
if 'date' in whatTo:
result['date'] = str(self.date)
if 'title' in whatTo:
result['title'] = self.title
if 'short_description' in whatTo:
result['short_description'] = self.short_description
if 'type' in whatTo:
result['type'] = self.type
if 'background_image' in whatTo:
result['background_image'] = self.background_image
if 'content' in whatTo:
result['content'] = self.content
return result
Jquery的:
$.post("http://127.0.0.1:5000/ajax/programme", {year: '2017', semester: 1}, function(result){
console.log(result);
});
所以我无法相信烧瓶和js与这一点不相容,或者sqlalchemy devs没有开发出什么东西。我必须错过一些东西!
谢谢
答案 0 :(得分:0)
您可能需要考虑可以序列化任何Python对象的https://jsonpickle.github.io:
shows_list = Shows.query.all()
return Response(jsonpickle.encode(shows_list), mimetype='application/json')
在使用SQLAlchemy进行100%清理之前,您应该考虑将实例设置为瞬态或分离。 http://docs.sqlalchemy.org/en/latest/orm/session_api.html#sqlalchemy.orm.session.make_transient
SQLAlchemy和jsonpickle两个具有隐藏字段的仪器类都能够正确反序列化,因此如果您不小心将其重新附加到会话中,那么这些可能会污染有效负载。如果您的用例是暂时/只读访问权限,您可以按照以下方式擦除代码:
for show in show_list:
sqla_session.make_transient(show)
show._sa_instance_state = None
return Response(jsonpickle.encode(shows_list, unpicklable=False),
mimetype='application/json')