Maintain order when dumping dict to JSON

后端 未结 2 372
猫巷女王i
猫巷女王i 2020-12-11 17:45

I want to serialize the results of a database query to JSON. Each row has a number of columns, with I add to a dict. The columns are in a certain order, but when I seriali

相关标签:
2条回答
  • 2020-12-11 18:19

    It's not possible using Flask's jsonify(), but it is possible using just plain vanilla json.dumps(). The only catch is that you have to get the content length to match, since this is set in the response headers:

    import json
    from collections import OrderedDict
    from flask import Flask, jsonify
    app = Flask(__name__)
    
    @app.route("/unordered")
    def unordered_dict():
        d = OrderedDict([('e',1),('d',2),('c',3),('b',4),('a',5)])
        output = jsonify(d)
        return output
    
    @app.route("/ordered")
    def ordered_dict():
        d = OrderedDict([('e',1),('d',2),('c',3),('b',4),('a',5)])
        response = json.dumps(d)
        placeholder = '_'*(len(response)-2) # Create a placeholder, -2 due to ""
        output = jsonify(placeholder) # This needs to be the same length as the response
        output.response[0] = response + '\n' # Replace with the actual response
        return output
    

    The first will return by default in alphabetical key order, or random order if app.config['JSON_SORT_KEYS'] = False. The second should return the keys in the order specified.

    Caution: As the others noted, the JSON specification doesn't require order. However, it seems most browsers respect the order anyway, so this can be used in cases where order would be nice but not critical. If order is critical, then your only option is to convert to a list before converting to JSON.

    (Note: prior to https://github.com/pallets/flask/issues/1877, the Content-Length wasn't explicitly set, so it was much simpler!)

    0 讨论(0)
  • 2020-12-11 18:20

    Python dicts and JSON objects have no order, so there is no direct way to do this. In Python, OrderedDict maintains the insert order, but there is no equivalent in JSON. You can convert the dict to a list of its items, since lists are ordered.

    data = OrderedDict()
    data['a'] = 1
    data['b'] = 2
    jsonify(data=list(data.items()))
    

    If you need to know that this particular list is actually an ordered dict, you can use a tagging scheme to tag the type of each value. This gets considerably more complicated. You can find an example of it in Flask's session serializer.

    0 讨论(0)
提交回复
热议问题