Browse Source

Make `/people` fast(er)

Maarten van den Berg 3 years ago
parent
commit
17ec2d51ac
1 changed files with 34 additions and 3 deletions
  1. 34 3
      piket_server/__init__.py

+ 34 - 3
piket_server/__init__.py

4
 
4
 
5
 import datetime
5
 import datetime
6
 import os
6
 import os
7
+from collections import defaultdict
7
 
8
 
8
 from sqlalchemy.exc import SQLAlchemyError
9
 from sqlalchemy.exc import SQLAlchemyError
9
 from sqlalchemy import func
10
 from sqlalchemy import func
49
                 .filter_by(consumption_type=ct)
50
                 .filter_by(consumption_type=ct)
50
                 .filter_by(reversed=False)
51
                 .filter_by(reversed=False)
51
                 .count()
52
                 .count()
52
-                for ct in ConsumptionType.query.all()
53
+                for ct in ConsumptionType.query.filter_by(active=True).all()
53
             },
54
             },
54
         }
55
         }
55
 
56
 
253
 @app.route("/people", methods=["GET"])
254
 @app.route("/people", methods=["GET"])
254
 def get_people():
255
 def get_people():
255
     """ Return a list of currently known people. """
256
     """ Return a list of currently known people. """
256
-    people = Person.query.order_by(Person.name).all()
257
     q = Person.query.order_by(Person.name)
257
     q = Person.query.order_by(Person.name)
258
     if request.args.get("active"):
258
     if request.args.get("active"):
259
         active_status = request.args.get("active", type=int)
259
         active_status = request.args.get("active", type=int)
260
         q = q.filter_by(active=active_status)
260
         q = q.filter_by(active=active_status)
261
     people = q.all()
261
     people = q.all()
262
-    result = [person.as_dict for person in people]
262
+
263
+    engine = db.get_engine()
264
+    query = '''
265
+        SELECT
266
+            consumptions.person_id,
267
+            consumptions.consumption_type_id,
268
+            COUNT(*)
269
+        FROM consumptions
270
+        JOIN consumption_types
271
+            ON consumptions.consumption_type_id = consumption_types.consumption_type_id
272
+        WHERE
273
+            consumptions.settlement_id IS NULL
274
+            AND consumptions.reversed = 0
275
+        GROUP BY consumptions.person_id, consumptions.consumption_type_id;
276
+    '''
277
+    raw_counts = engine.execute(query)
278
+
279
+    counts: 'Dict[int, Dict[str, int]]' = defaultdict(dict)
280
+    for person_id, consumption_type_id, count in raw_counts:
281
+        counts[person_id][str(consumption_type_id)] = count
282
+
283
+    result = [
284
+        {
285
+            "name": person.name,
286
+            "active": person.active,
287
+            "person_id": person.person_id,
288
+            "consumptions": counts[person.person_id]
289
+        }
290
+        for person in people
291
+    ]
292
+
293
+    # result = [person.as_dict for person in people]
263
     return jsonify(people=result)
294
     return jsonify(people=result)
264
 
295
 
265
 
296