@@ -60,6 +60,21 @@ def _duplicate_query_key(query):
60
60
return (query ["raw_sql" ], saferepr (raw_params ))
61
61
62
62
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 > 1 :
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
+
63
78
class SQLPanel (Panel ):
64
79
"""
65
80
Panel that displays information about the SQL queries run while processing
@@ -156,8 +171,8 @@ def disable_instrumentation(self):
156
171
def generate_stats (self , request , response ):
157
172
colors = contrasting_color_generator ()
158
173
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 )
161
176
162
177
if self ._queries :
163
178
width_ratio_tally = 0
@@ -180,8 +195,10 @@ def generate_stats(self, request, response):
180
195
# the last query recorded for each DB alias
181
196
last_by_alias = {}
182
197
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
+ )
185
202
186
203
trans_id = query .get ("trans_id" )
187
204
prev_query = last_by_alias .get (alias , {})
@@ -234,48 +251,13 @@ def generate_stats(self, request, response):
234
251
if final_query .get ("trans_id" ) is not None :
235
252
final_query ["ends_trans" ] = True
236
253
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
+ )
279
261
280
262
self .record_stats (
281
263
{
0 commit comments