如何解决如何将 SqlAlchemy 结果序列化为 JSON?
平面实现
你可以使用这样的东西:
from sqlalchemy.ext.declarative import DeclarativeMeta
class AlchemyEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj.__class__, DeclarativeMeta):
# an sqlAlchemy class
fields = {}
for field in [x for x in dir(obj) if not x.startswith('_') and x != 'Metadata']:
data = obj.__getattribute__(field)
try:
json.dumps(data) # this will fail on non-encodable values, like other classes
fields[field] = data
except TypeError:
fields[field] = None
# a json-encodable dict
return fields
return json.JSONEncoder.default(self, obj)
然后使用以下方法转换为 JSON:
c = YourAlchemyClass()
print json.dumps(c, cls=AlchemyEncoder)
它将忽略不可编码的字段(将它们设置为“无”)。
它不会自动扩展关系(因为这可能导致自我引用,并永远循环)。
递归的非循环实现
但是,如果您宁愿永远循环,您可以使用:
from sqlalchemy.ext.declarative import DeclarativeMeta
def new_alchemy_encoder():
_visited_objs = []
class AlchemyEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj.__class__, DeclarativeMeta):
# don't re-visit self
if obj in _visited_objs:
return None
_visited_objs.append(obj)
# an sqlAlchemy class
fields = {}
for field in [x for x in dir(obj) if not x.startswith('_') and x != 'Metadata']:
fields[field] = obj.__getattribute__(field)
# a json-encodable dict
return fields
return json.JSONEncoder.default(self, obj)
return AlchemyEncoder
然后使用以下方法对对象进行编码:
print json.dumps(e, cls=new_alchemy_encoder(), check_circular=False)
这将编码所有孩子,以及他们所有的孩子,以及他们所有的孩子......基本上可能对您的整个数据库进行编码。当它到达之前编码的东西时,它会将其编码为“无”。
递归的、可能循环的、选择性的实现
另一种可能更好的选择是能够指定要扩展的字段:
def new_alchemy_encoder(revisit_self = False, fields_to_expand = []):
_visited_objs = []
class AlchemyEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj.__class__, DeclarativeMeta):
# don't re-visit self
if revisit_self:
if obj in _visited_objs:
return None
_visited_objs.append(obj)
# go through each field in this sqlalchemy class
fields = {}
for field in [x for x in dir(obj) if not x.startswith('_') and x != 'Metadata']:
val = obj.__getattribute__(field)
# is this field another sqlalchemy object, or a list of sqlalchemy objects?
if isinstance(val.__class__, DeclarativeMeta) or (isinstance(val, list) and len(val) > 0 and isinstance(val[0].__class__, DeclarativeMeta)):
# unless we're expanding this field, stop here
if field not in fields_to_expand:
# not expanding this field: set it to None and continue
fields[field] = None
continue
fields[field] = val
# a json-encodable dict
return fields
return json.JSONEncoder.default(self, obj)
return AlchemyEncoder
您现在可以使用以下命令调用它:
print json.dumps(e, cls=new_alchemy_encoder(False, ['parents']), check_circular=False)
例如,仅扩展名为“父母”的 sqlAlchemy 字段。
解决方法
Django 有一些很好的自动序列化从 DB 到 JSON 格式的 ORM 模型。
如何将 SQLAlchemy 查询结果序列化为 JSON 格式?
我尝试过jsonpickle.encode
,但它对查询对象本身进行编码。我试过json.dumps(items)
但它返回
TypeError: <Product('3','some name','some desc')> is not JSON serializable
将 SQLAlchemy ORM 对象序列化为 JSON /XML 真的那么难吗?它没有任何默认的序列化程序吗?现在序列化 ORM 查询结果是很常见的任务。
我需要的只是返回 SQLAlchemy 查询结果的 JSON 或 XML 数据表示。
javascript datagird中需要使用JSON/XML格式的SQLAlchemy对象查询结果(JQGrid
http://www.trirand.com/blog/)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。