【问题标题】:How to create sqlalchemy to json如何创建 sqlalchemy 到 json
【发布时间】:2013-02-01 22:13:36
【问题描述】:

我有一个 sqlalchemy 结果

labels = session.query(
         LabelsData, 
         LabelsData.id, 
         LabelsData.name, 
         LabelsData.color
         ).filter(LabelsData.deleted==False).all()

我想将此结果转换为 JSON,但我该怎么做呢?

【问题讨论】:

标签: python json sqlalchemy


【解决方案1】:

看起来您的 LabelsData 对象是一个 SQLAlchemy 模型。在将其转储到 JSON 之前,您需要对其进行序列化。这是一个简短的示例,它从您的 LabelsData 对象中提取所有列并将查询结果转换为 JSON:

from json import dumps
from sqlalchemy.orm import class_mapper

def serialize(model):
  """Transforms a model into a dictionary which can be dumped to JSON."""
  # first we get the names of all the columns on your model
  columns = [c.key for c in class_mapper(model.__class__).columns]
  # then we return their values in a dict
  return dict((c, getattr(model, c)) for c in columns)

# we can then use this for your particular example
serialized_labels = [
  serialize(label)
  for label in session.query(LabelsData).filter(LabelsData.deleted == False)
]
your_json = dumps(serialized_labels)

【讨论】:

    【解决方案2】:
    from collections import OrderedDict
    
    class DictSerializable(object):
        def _asdict(self):
            result = OrderedDict()
            for key in self.__mapper__.c.keys():
                result[key] = getattr(self, key)
            return result
    

    来自here,似乎需要simplejson。希望对您有所帮助...

    更新:再看一遍,它是一本字典,您可以由 python 中的任何 json 模块转储。

    【讨论】:

    • 需要处理不能直接序列化的日期时间值.. 使用下面给出的东西 :: def handler(o): if hasattr(o, 'isoformat') and callable(o.isoformat) : return o.isoformat() raise TypeError("Can't serialize %r" % (o,)) jsonize = lambda d: json.dumps(d, default=_handler) 由link@ 的'Thomas Dignan'提供跨度>
    【解决方案3】:

    看起来 sqlalchemy 已经有了一个 http://docs.sqlalchemy.org/en/latest/core/serializer.html

    from sqlalchemy.ext.serializer import loads, dumps
    metadata = MetaData(bind=some_engine)
    Session = scoped_session(sessionmaker())
    
    # ... define mappers
    
    query = Session.query(MyClass).filter(MyClass.somedata=='foo').order_by(MyClass.sortkey)
    
    # pickle the query
    serialized = dumps(query)
    
    # unpickle.  Pass in metadata + scoped_session
    query2 = loads(serialized, metadata, Session)
    
    print query2.all()
    

    【讨论】:

    • 这似乎只适用于查询本身,而不适用于其中包含的数据。我认为 OP 正在询问将查询对象的结果编码为 json。
    【解决方案4】:

    这篇博文提供了我所采用的解决方案: http://blogs.gnome.org/danni/2013/03/07/generating-json-from-sqlalchemy-objects/

    使用的策略是将 .todict 方法直接包含到 Base mixin 中,该方法迭代父类的 sqlalchemy 列。

    或者,Nande 使用 sqlalchemy.ext.serializer 的方法 (https://stackoverflow.com/a/19602809/837575) 效果很好,如果您尝试通过网络对数据进行序列化,但不一定需要它作为 json。

    【讨论】:

    • 链接的博客文章没有代码格式。只有黑色/白色的文本块。
    【解决方案5】:

    我添加了这个anwser,因为它是@mekarpeles 和@hd1 的混合体。我的意思是我没有修改对象的 sqlalchemy 层次结构,只是委托给一个简单的JSONEncoder

    # given that you have 
    Base = declarative_base()
    
    class SqlAlchemyModelEncoder(json.JSONEncoder):
        def default(self, obj):
            if isinstance(obj, Base):
                result = OrderedDict()
                for key in obj.__mapper__.c.keys():
                    result[key] = getattr(obj, key)
                return result
            return json.JSONEncoder.default(self, obj)
    

    如果您的模型使用不可序列化的类(例如日期时间),您必须将它们添加到编码器:

    if isinstance(obj, datetime):
        return obj.isoformat()
    

    然后我将它与 jinja2 上下文过滤器一起使用:

    @contextfilter
    def tojson(ctx, model, *elements, **kw):
        return json.dumps(model, cls=SqlAlchemyModelEncoder)
    

    【讨论】:

      【解决方案6】:

      https://github.com/TaylorHere/PythonSerializer
      上面的链接可以帮助你,它是一个小脚本,可以简单地将sql查询结果序列化为list或dict,就像这样:

      #Useage with flask and SQLalchemy
      from serializer import serializer
      def my_location():
          if request.method == 'GET':
              user = db_session.query(User).filter(
              User.openid == session['user_id']).first()
              addresses = user.addresses
              return jsonify({'data': serializer(addresses.instance, 'sqlalchemy')})
      

      【讨论】:

        猜你喜欢
        • 2016-06-06
        • 1970-01-01
        • 2018-12-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-10-15
        • 2023-02-02
        • 2016-08-13
        相关资源
        最近更新 更多