Calculating the billing units per month was taking too long for a services with a lot of data.

The query now does the sum per month.
This commit is contained in:
Rebecca Law
2017-01-09 11:13:24 +00:00
parent 098567c151
commit 17767dfa62
2 changed files with 22 additions and 28 deletions

View File

@@ -1,14 +1,13 @@
import pytz import pytz
from datetime import ( from datetime import (
datetime, datetime,
timedelta, timedelta,
date date)
)
from itertools import groupby
from flask import current_app from flask import current_app
from werkzeug.datastructures import MultiDict from werkzeug.datastructures import MultiDict
from sqlalchemy import (desc, func, or_, and_, asc) from sqlalchemy import (desc, func, or_, and_, asc, extract)
from sqlalchemy.orm import joinedload from sqlalchemy.orm import joinedload
from app import db, create_uuid from app import db, create_uuid
@@ -217,23 +216,16 @@ def get_notification_billable_unit_count_per_month(service_id, year):
start, end = get_financial_year(year) start, end = get_financial_year(year)
notifications = db.session.query( notifications = db.session.query(
NotificationHistory.created_at, func.date_trunc("month", (NotificationHistory.created_at + extract("timezone", func.timezone("Europe/London", NotificationHistory.created_at)) * timedelta(seconds=1))),
NotificationHistory.billable_units func.sum(NotificationHistory.billable_units)
).order_by(
NotificationHistory.created_at
).filter( ).filter(
NotificationHistory.billable_units != 0, NotificationHistory.billable_units != 0,
NotificationHistory.service_id == service_id, NotificationHistory.service_id == service_id,
NotificationHistory.created_at >= start, NotificationHistory.created_at >= start,
NotificationHistory.created_at < end NotificationHistory.created_at < end
) ).group_by(func.date_trunc("month", (NotificationHistory.created_at + extract("timezone", func.timezone("Europe/London", NotificationHistory.created_at)) * timedelta(seconds=1)))).all()
return [ return [(datetime.strftime(x[0], "%B"), x[1]) for x in notifications]
(month, sum(count for _, count in row))
for month, row in groupby(
notifications, lambda row: get_bst_month(row[0])
)
]
@statsd(namespace="dao") @statsd(namespace="dao")

View File

@@ -700,21 +700,23 @@ def test_get_all_notifications_for_job_by_status(notify_db, notify_db_session, s
def test_get_notification_billable_unit_count_per_month(notify_db, notify_db_session, sample_service): def test_get_notification_billable_unit_count_per_month(notify_db, notify_db_session, sample_service):
for year, month, day in ( for year, month, day, hour, minute, second in (
(2017, 1, 15), # ↓ 2016 financial year (2017, 1, 15, 23, 59, 59), # ↓ 2016 financial year
(2016, 8, 1), (2016, 9, 30, 23, 59, 59), # counts in October (BST conversion)
(2016, 7, 15), (2016, 6, 30, 23, 50, 20),
(2016, 4, 15), (2016, 7, 15, 9, 20, 25),
(2016, 4, 15), (2016, 4, 15, 12, 30, 00),
(2016, 4, 1), # ↓ 2015 financial year (2016, 4, 1, 1, 1, 00),
(2016, 3, 31), (2016, 4, 1, 0, 0, 00), # ↓ 2015 financial year
(2016, 1, 15) (2016, 3, 20, 22, 40, 45),
(2015, 11, 20, 22, 40, 45),
(2016, 1, 15, 2, 30, 40)
): ):
sample_notification( sample_notification(
notify_db, notify_db_session, service=sample_service, notify_db, notify_db_session, service=sample_service,
created_at=datetime( created_at=datetime(
year, month, day, 0, 0, 0, 0 year, month, day, hour, minute, second, 0
) - timedelta(hours=1, seconds=1) # one second before midnight )
) )
for financial_year, months in ( for financial_year, months in (
@@ -724,11 +726,11 @@ def test_get_notification_billable_unit_count_per_month(notify_db, notify_db_ses
), ),
( (
2016, 2016,
[('April', 2), ('July', 2), ('January', 1)] [('April', 2), ('July', 2), ('October', 1), ('January', 1)]
), ),
( (
2015, 2015,
[('January', 1), ('March', 2)] [('November', 1), ('January', 1), ('March', 1), ('April', 1)]
), ),
( (
2014, 2014,