@@ -60,6 +60,21 @@ def _duplicate_query_key(query):
6060 return (query ["raw_sql" ], saferepr (raw_params ))
6161
6262
63+ def _process_query_groups (query_groups , databases , colors , name ):
64+ counts = defaultdict (int )
65+ for (alias , key ), query_group in query_groups .items ():
66+ count = len (query_group )
67+ # Queries are similar / duplicates only if there are at least 2 of them.
68+ if count > 2 :
69+ color = next (colors )
70+ for query in query_group :
71+ query [f"{ name } _count" ] = count
72+ query [f"{ name } _color" ] = color
73+ counts [alias ] += count
74+ for alias , db_info in databases .items ():
75+ db_info [f"{ name } _count" ] = counts [alias ]
76+
77+
6378class SQLPanel (Panel ):
6479 """
6580 Panel that displays information about the SQL queries run while processing
@@ -156,8 +171,8 @@ def disable_instrumentation(self):
156171 def generate_stats (self , request , response ):
157172 colors = contrasting_color_generator ()
158173 trace_colors = defaultdict (lambda : next (colors ))
159- query_similar = defaultdict (lambda : defaultdict ( int ) )
160- query_duplicates = defaultdict (lambda : defaultdict ( int ) )
174+ similar_query_groups = defaultdict (list )
175+ duplicate_query_groups = defaultdict (list )
161176
162177 if self ._queries :
163178 width_ratio_tally = 0
@@ -180,8 +195,10 @@ def generate_stats(self, request, response):
180195 # the last query recorded for each DB alias
181196 last_by_alias = {}
182197 for alias , query in self ._queries :
183- query_similar [alias ][_similar_query_key (query )] += 1
184- query_duplicates [alias ][_duplicate_query_key (query )] += 1
198+ similar_query_groups [(alias , _similar_query_key (query ))].append (query )
199+ duplicate_query_groups [(alias , _duplicate_query_key (query ))].append (
200+ query
201+ )
185202
186203 trans_id = query .get ("trans_id" )
187204 prev_query = last_by_alias .get (alias , {})
@@ -234,48 +251,13 @@ def generate_stats(self, request, response):
234251 if final_query .get ("trans_id" ) is not None :
235252 final_query ["ends_trans" ] = True
236253
237- # Queries are similar / duplicates only if there's as least 2 of them.
238- # Also, to hide queries, we need to give all the duplicate groups an id
239- query_colors = contrasting_color_generator ()
240- query_similar_colors = {
241- alias : {
242- query : (similar_count , next (query_colors ))
243- for query , similar_count in queries .items ()
244- if similar_count >= 2
245- }
246- for alias , queries in query_similar .items ()
247- }
248- query_duplicates_colors = {
249- alias : {
250- query : (duplicate_count , next (query_colors ))
251- for query , duplicate_count in queries .items ()
252- if duplicate_count >= 2
253- }
254- for alias , queries in query_duplicates .items ()
255- }
256-
257- for alias , query in self ._queries :
258- try :
259- (query ["similar_count" ], query ["similar_color" ]) = query_similar_colors [
260- alias
261- ][_similar_query_key (query )]
262- (
263- query ["duplicate_count" ],
264- query ["duplicate_color" ],
265- ) = query_duplicates_colors [alias ][_duplicate_query_key (query )]
266- except KeyError :
267- pass
268-
269- for alias , alias_info in self ._databases .items ():
270- try :
271- alias_info ["similar_count" ] = sum (
272- e [0 ] for e in query_similar_colors [alias ].values ()
273- )
274- alias_info ["duplicate_count" ] = sum (
275- e [0 ] for e in query_duplicates_colors [alias ].values ()
276- )
277- except KeyError :
278- pass
254+ group_colors = contrasting_color_generator ()
255+ _process_query_groups (
256+ similar_query_groups , self ._databases , group_colors , "similar"
257+ )
258+ _process_query_groups (
259+ duplicate_query_groups , self ._databases , group_colors , "duplicate"
260+ )
279261
280262 self .record_stats (
281263 {
0 commit comments