Python Flask Sqlalchemy模型通过调用模型返回不同的结果。uu dict_uuu(有时显示backrefs,有时显示don';t)
我想从查询中获得结果并将其与Python Flask Sqlalchemy模型通过调用模型返回不同的结果。uu dict_uuu(有时显示backrefs,有时显示don';t),python,json,flask,sqlalchemy,flask-sqlalchemy,Python,Json,Flask,Sqlalchemy,Flask Sqlalchemy,我想从查询中获得结果并将其与jsonify一起发送给客户端,我创建了一个函数来获取模型的实例,使用其“dict”属性删除未使用的值,如“\sa\u instance\u state”,然后将新字典作为jsonified对象返回给客户端。 这是我的密码: def display(Object): data= Object.__dict__.copy() del data['_sa_instance_state'] return data` user
jsonify
一起发送给客户端,我创建了一个函数来获取模型的实例,使用其“dict”属性删除未使用的值,如“\sa\u instance\u state”
,然后将新字典作为jsonified对象返回给客户端。
这是我的密码:
def display(Object):
data= Object.__dict__.copy()
del data['_sa_instance_state']
return data`
user = User.query.first()
@app.route('/')
def main():
return jsonify(display(user))
有时我会犯这样的错误
TypeError:类型为Admin的对象不可JSON序列化
管理员在哪里
另一个模型
,在用户模型中有backref。
奇怪的事情发生在这里,因为有时候不做任何改变,我就不会出错。
当我试图找出jupyter笔记本中发生的事情时,我发现
\uu dict\uuu
在jupyter笔记本中不显示backrefs,但有时在我从flask应用程序调用它时,它会显示backrefs。不要在SQLAlchemy模型上使用\uu dict\uu
。是的,可能存在反向引用,其他SQLAlchemy特定信息也可能存在
你可以用它来弄到那个。然后,您可以决定在JSON中反映什么以及应该忽略什么:
from operator import attrgetter
from sqlalchemy import inspect
def display(object, only_loaded=False):
insp = inspect(object)
assert insp.is_instance
value = attrgetter('loaded_value' if only_loaded else 'value')
return {
name: value(attr) for name, attr in insp.attrs.items()
if name not in insp.mapper.relationships
}
上面使用跳过任何相关对象。处理相关对象的另一种方法是递归地将它们转换为字典:
def display(object, include_related=True, only_loaded=False, seen=None):
insp = inspect(object)
assert insp.is_instance
value = attrgetter('loaded_value' if only_loaded else 'value')
result = {
name: value(attr) for name, attr in insp.attrs.items()
if name not in insp.mapper.relationships
}
if include_related:
if seen is None:
seen = set()
seen.add(id(object))
for name, rel in insp.mapper.relationships.items():
related = value(insp.attrs[name])
if related is not None:
if rel.uselist:
displays = result[name] = []
for r in related:
if id(r) in seen:
continue
displays.append(display(r, True, only_loaded, seen))
else:
if id(related) in seen:
continue
result[name] = display(related, True, only_loaded)
return result
但要考虑到,使用双向关系对象,您可以很快反映出比您预期的更大的数据库块
就我个人而言,我发现只需在生成字典的模型中添加一个as_dict()
方法,或者在该模型上使用一个Flask附加组件,就更容易了。不要在SQLAlchemy模型上使用\u dict\uu
。是的,可能存在反向引用,其他SQLAlchemy特定信息也可能存在
你可以用它来弄到那个。然后,您可以决定在JSON中反映什么以及应该忽略什么:
from operator import attrgetter
from sqlalchemy import inspect
def display(object, only_loaded=False):
insp = inspect(object)
assert insp.is_instance
value = attrgetter('loaded_value' if only_loaded else 'value')
return {
name: value(attr) for name, attr in insp.attrs.items()
if name not in insp.mapper.relationships
}
上面使用跳过任何相关对象。处理相关对象的另一种方法是递归地将它们转换为字典:
def display(object, include_related=True, only_loaded=False, seen=None):
insp = inspect(object)
assert insp.is_instance
value = attrgetter('loaded_value' if only_loaded else 'value')
result = {
name: value(attr) for name, attr in insp.attrs.items()
if name not in insp.mapper.relationships
}
if include_related:
if seen is None:
seen = set()
seen.add(id(object))
for name, rel in insp.mapper.relationships.items():
related = value(insp.attrs[name])
if related is not None:
if rel.uselist:
displays = result[name] = []
for r in related:
if id(r) in seen:
continue
displays.append(display(r, True, only_loaded, seen))
else:
if id(related) in seen:
continue
result[name] = display(related, True, only_loaded)
return result
但要考虑到,使用双向关系对象,您可以很快反映出比您预期的更大的数据库块
就我个人而言,我发现只需将as_dict()
方法添加到生成字典以反映的模型中,或者使用Flask附加组件,就更容易了