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)
JSON usually doesn't care about the order of the items. Therefore, when we dump a Python dictionary to a JSON string, the order of the items will be kept as-is. However, if we do want to sort the converted JSON string by the item keys, we can easily set sort_keys parameter to True .
loads() doesn't keep order [duplicate] Bookmark this question. Show activity on this post.
A dictionary is a collection which is unordered, mutable, and indexed. In Python, dictionaries are written with curly brackets {}, and they have key:value pair. Updated in Python version 3.7. Dictionaries preserve insertion order.
Python's OrderedDict is a dict subclass that preserves the order in which key-value pairs, commonly known as items, are inserted into the dictionary. When you iterate over an OrderedDict object, items are traversed in the original order. If you update the value of an existing key, then the order remains unchanged.
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.
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!)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With