Fixed #32226 -- Fixed JSON format of QuerySet.explain() on PostgreSQL.

This commit is contained in:
Wu Haotian 2021-06-30 18:45:10 +08:00 committed by Mariusz Felisiak
parent b3b04ad211
commit aba9c2de66
3 changed files with 12 additions and 1 deletions

View File

@ -974,6 +974,7 @@ answer newbie questions, and generally made Django that much better:
Wilson Miner <wminer@gmail.com> Wilson Miner <wminer@gmail.com>
Wim Glenn <hey@wimglenn.com> Wim Glenn <hey@wimglenn.com>
wojtek wojtek
Wu Haotian <whtsky@gmail.com>
Xavier Francisco <xavier.n.francisco@gmail.com> Xavier Francisco <xavier.n.francisco@gmail.com>
Xia Kai <https://blog.xiaket.org/> Xia Kai <https://blog.xiaket.org/>
Yann Fouillat <gagaro42@gmail.com> Yann Fouillat <gagaro42@gmail.com>

View File

@ -1,4 +1,5 @@
import collections import collections
import json
import re import re
from functools import partial from functools import partial
from itertools import chain from itertools import chain
@ -1250,9 +1251,10 @@ class SQLCompiler:
result = list(self.execute_sql()) result = list(self.execute_sql())
# Some backends return 1 item tuples with strings, and others return # Some backends return 1 item tuples with strings, and others return
# tuples with integers and strings. Flatten them out into strings. # tuples with integers and strings. Flatten them out into strings.
output_formatter = json.dumps if self.query.explain_format == 'json' else str
for row in result[0]: for row in result[0]:
if not isinstance(row, str): if not isinstance(row, str):
yield ' '.join(str(c) for c in row) yield ' '.join(output_formatter(c) for c in row)
else: else:
yield row yield row

View File

@ -1,3 +1,4 @@
import json
import unittest import unittest
import xml.etree.ElementTree import xml.etree.ElementTree
@ -39,6 +40,13 @@ class ExplainTests(TestCase):
self.fail( self.fail(
f'QuerySet.explain() result is not valid XML: {e}' f'QuerySet.explain() result is not valid XML: {e}'
) )
elif format == 'json':
try:
json.loads(result)
except json.JSONDecodeError as e:
self.fail(
f'QuerySet.explain() result is not valid JSON: {e}'
)
@skipUnlessDBFeature('validates_explain_options') @skipUnlessDBFeature('validates_explain_options')
def test_unknown_options(self): def test_unknown_options(self):