Reputation: 7347
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 serialize the data the order changes. I tried using an OrderedDict
, but still saw the same issue. How can I maintain the order of the columns?
res = {'a': i[0], 'b': i[1], 'c': i[2]}
return jsonify(res=res)
res = OrderedDict()
res['a'] = i[0]
res['b'] = i[1]
res['c'] = i[3]
return jsonify(res=res)
Upvotes: 10
Views: 5788
Reputation: 341
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!)
Upvotes: 4
Reputation: 127190
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.
Upvotes: 7