From c9753836b66a5f6c0e208be3ad50328fb6dc8b36 Mon Sep 17 00:00:00 2001 From: Baptiste Jonglez Date: Thu, 8 Jul 2021 08:58:40 +0200 Subject: [PATCH] Fix SQL query in has_multiple_currencies The previous query was working fine on sqlite and mariadb, but not on postgresql : return self.get_bills_unordered().group_by(Bill.original_currency).count() > 1 psycopg2.errors.GroupingError: column "bill.id" must appear in the GROUP BY clause or be used in an aggregate function The failing SQL query was: [SQL: SELECT count(*) AS count_1 FROM (SELECT bill.id AS bill_id, ... FROM bill JOIN person ON person.id = bill.payer_id JOIN project ON project.id = person.project_id WHERE bill.payer_id = person.id AND person.project_id = project.id AND project.id = %(id_1)s GROUP BY bill.original_currency) AS anon_1] The problem is that sqlalchemy creates a subquery for postgresql, and the internal query does not make sense. GROUP BY is not actually useful, we simply need to count the number of distinct currencies in the list of bills. --- ihatemoney/models.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/ihatemoney/models.py b/ihatemoney/models.py index 0ae2ef72..04415fa6 100644 --- a/ihatemoney/models.py +++ b/ihatemoney/models.py @@ -219,8 +219,14 @@ class Project(db.Model): return self.get_bills_unordered().count() > 0 def has_multiple_currencies(self): - """Return if multiple currencies are used""" - return self.get_bills_unordered().group_by(Bill.original_currency).count() > 1 + """Returns True if multiple currencies are used""" + # It would be more efficient to do the counting in the database, + # but this is called very rarely so we can tolerate if it's a bit + # slow. And doing this in Python is much more readable, see #784. + nb_currencies = len( + set(bill.original_currency for bill in self.get_bills_unordered()) + ) + return nb_currencies > 1 def get_bills_unordered(self): """Base query for bill list"""