Explorar o código

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

Wu Haotian %!s(int64=3) %!d(string=hai) anos
pai
achega
aba9c2de66
Modificáronse 3 ficheiros con 12 adicións e 1 borrados
  1. 1 0
      AUTHORS
  2. 3 1
      django/db/models/sql/compiler.py
  3. 8 0
      tests/queries/test_explain.py

+ 1 - 0
AUTHORS

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

+ 3 - 1
django/db/models/sql/compiler.py

@@ -1,4 +1,5 @@
 import collections
+import json
 import re
 from functools import partial
 from itertools import chain
@@ -1250,9 +1251,10 @@ class SQLCompiler:
         result = list(self.execute_sql())
         # Some backends return 1 item tuples with strings, and others return
         # 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]:
             if not isinstance(row, str):
-                yield ' '.join(str(c) for c in row)
+                yield ' '.join(output_formatter(c) for c in row)
             else:
                 yield row
 

+ 8 - 0
tests/queries/test_explain.py

@@ -1,3 +1,4 @@
+import json
 import unittest
 import xml.etree.ElementTree
 
@@ -39,6 +40,13 @@ class ExplainTests(TestCase):
                                 self.fail(
                                     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')
     def test_unknown_options(self):