Запрос SQLAlchemy дает противоречивые результаты в зависимости от типа базы данных

У меня есть приложение Flask, которое отображает простую статистику о количестве книг, введенных пользователем, и о том, сколько книг он помечает как прочитанное каждый месяц. При локальном тестировании запроса в базе данных SQLite3 все работает нормально. Однако, когда я выполняю развертывание на Heroku, использующем базу данных PostgreSQL, статистика получается неправильной. Запрос выглядит так:

books_group = db.session.query(extract("month", Book.timestamp), func.count(Book.id), func.count(Book.read)).filter(Book.user_id == current_user.id).group_by(extract("month", Book.timestamp)).all()

При локальном запуске вывод выглядит следующим образом: [(4, 27, 21)] где первое число — это месяц, второе — количество введенных книг, а третье — количество прочитанных книг. При работе на Heroku вывод: [(4.0, 10, 10)] Независимо от того, что я делаю, количество введенных книг и количество книг, помеченных как прочитанные, всегда одинаково, хотя вывод должен быть [(4.0, 10, 5)]

Моя модель выглядит так:

class Book(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(140))
    timestamp = db.Column(db.DateTime, index=True, default=datetime.utcnow)
    read = db.Column(db.Boolean, default=False)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'))

И данные выглядят так:

+----+--------+-----------------------+------+---------+
| id | title  |       timestamp       | read | user_id |
+----+--------+-----------------------+------+---------+
|  1 | Foo    | 17 apr. 2020 13:14:47 |    1 |       1 |
|  2 | Bar    | 17 apr. 2020 13:14:47 |    1 |       1 |
|  3 | Baz    | 18 apr. 2020 13:14:47 |    0 |       1 |
|  4 | Foobar | 18 apr. 2020 13:14:47 |    1 |       2 |
|  5 | BarBaz | 18 apr. 2020 13:14:47 |    0 |       2 |
|    | FooBaz | 19 apr. 2020 13:14:47 |    0 |       1 |
+----+--------+-----------------------+------+---------+

Что здесь происходит не так?

РЕДАКТИРОВАТЬ:

Решение, которое работало как для SQLite3, так и для PostgreSQL:

books_group = db.session.query(extract("month", Book.timestamp), func.count(Book.id), func.sum(cast(Book.read, Integer))).filter(Book.user_id == current_user.id).group_by(extract("month", Book.timestamp)).all()

person Stefan    schedule 19.04.2020    source источник
comment
@IljaEverilä Я отредактировал свой вопрос!   -  person Stefan    schedule 20.04.2020
comment
func.count(Book.read) подсчитывает, сколько раз Book.read не равно NULL. Если ваши данные не содержат NULL, учитывается каждая строка в группе.   -  person Ilja Everilä    schedule 20.04.2020
comment
Изменение кода на func.count(Book.read == True) приводит к тем же противоречивым результатам. Он работает на SQLite3, но не на PostgreSQL.   -  person Stefan    schedule 20.04.2020
comment
func.count(Book.read == True) не имеет значения. Если Book.read является логическим столбцом, то Book.read и Book.read == True эквивалентны. И если Book.read равно NULL, то результат Book.read == True также равен NULL. Поскольку COUNT(<expression>) подсчитывает, сколько раз выражение expression оценивается как отличное от NULL, несоответствия нет. Ваши данные в PostgreSQL, кажется, имеют нет NULL, в то время как данные в SQLite, кажется, имеют NULL.   -  person Ilja Everilä    schedule 20.04.2020
comment
Я понимаю. Да, PostgreSQL действительно не имеет значений NULL для столбца чтения. Итак, как мне подсчитать количество True так, чтобы это работало как для SQLite3, так и для PostgreSQL?   -  person Stefan    schedule 20.04.2020
comment
Вот как специфичные для PostgreSQL, так и переносимые способы подсчета true: "> stackoverflow.com/questions/37328779/   -  person Ilja Everilä    schedule 20.04.2020
comment
Оказывается, сумма и приведение к целочисленному решению сработали для меня! Спасибо!   -  person Stefan    schedule 20.04.2020