diff --git a/app/dao/notifications_dao.py b/app/dao/notifications_dao.py index 873ae7eea..cef0d9b55 100644 --- a/app/dao/notifications_dao.py +++ b/app/dao/notifications_dao.py @@ -1,8 +1,5 @@ import math -from sqlalchemy import ( - desc, - func -) +from sqlalchemy import desc from datetime import ( datetime, @@ -59,7 +56,7 @@ def dao_get_notification_statistics_for_service_and_previous_days(service_id, li service_id=service_id ).filter( NotificationStatistics.day.in_(( - (date.today() - timedelta(days=days_ago)).strftime('%Y-%m-%d') + (date.today() - timedelta(days=days_ago)) for days_ago in range(0, limit_days + 1) )) ).order_by( @@ -87,13 +84,13 @@ def dao_create_notification(notification, notification_type): }) update_count = db.session.query(NotificationStatistics).filter_by( - day=notification.created_at.strftime('%Y-%m-%d'), + day=notification.created_at.date(), service_id=notification.service_id ).update(update_query(notification_type, 'requested')) if update_count == 0: stats = NotificationStatistics( - day=notification.created_at.strftime('%Y-%m-%d'), + day=notification.created_at.date(), service_id=notification.service_id, sms_requested=1 if notification_type == TEMPLATE_TYPE_SMS else 0, emails_requested=1 if notification_type == TEMPLATE_TYPE_EMAIL else 0 @@ -149,7 +146,7 @@ def update_notification_status_by_id(notification_id, status, notification_stati notification = Notification.query.get(notification_id) db.session.query(NotificationStatistics).filter_by( - day=notification.created_at.strftime('%Y-%m-%d'), + day=notification.created_at.date(), service_id=notification.service_id ).update( update_query(notification.template.template_type, notification_statistics_status) @@ -172,7 +169,7 @@ def update_notification_status_by_reference(reference, status, notification_stat ).first() db.session.query(NotificationStatistics).filter_by( - day=notification.created_at.strftime('%Y-%m-%d'), + day=notification.created_at.date(), service_id=notification.service_id ).update( update_query(notification.template.template_type, notification_statistics_status) diff --git a/app/models.py b/app/models.py index fd7a3e596..3e1933ea9 100644 --- a/app/models.py +++ b/app/models.py @@ -121,7 +121,7 @@ class NotificationStatistics(db.Model): __tablename__ = 'notification_statistics' id = db.Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) - day = db.Column(db.String(255), nullable=False) + day = db.Column(db.Date, index=True, nullable=False, unique=False, default=datetime.date.today) service_id = db.Column(UUID(as_uuid=True), db.ForeignKey('services.id'), index=True, nullable=False) service = db.relationship('Service', backref=db.backref('service_notification_stats', lazy='dynamic')) emails_requested = db.Column(db.BigInteger, index=False, unique=False, nullable=False, default=0) diff --git a/migrations/versions/0004_notification_stats_date.py b/migrations/versions/0004_notification_stats_date.py new file mode 100644 index 000000000..8edd522ad --- /dev/null +++ b/migrations/versions/0004_notification_stats_date.py @@ -0,0 +1,49 @@ +"""empty message + +Revision ID: 0004_notification_stats_date +Revises: 0003_add_service_history +Create Date: 2016-04-20 13:59:01.132535 + +""" + +# revision identifiers, used by Alembic. +revision = '0004_notification_stats_date' +down_revision = '0003_add_service_history' + +from alembic import op +import sqlalchemy as sa + + +def upgrade(): + ### commands auto generated by Alembic - please adjust! ### + op.drop_constraint('uix_service_to_day', 'notification_statistics') + op.alter_column('notification_statistics', 'day', new_column_name='day_string') + op.add_column('notification_statistics', sa.Column('day', sa.Date(), nullable=True)) + + op.get_bind() + op.execute("UPDATE notification_statistics ns1 SET day = (SELECT to_date(day_string, 'YYYY-MM-DD') FROM notification_statistics ns2 WHERE ns1.id = ns2.id)") + + op.alter_column('notification_statistics', 'day', nullable=False) + op.create_index(op.f('ix_notification_statistics_day'), 'notification_statistics', ['day'], unique=False) + op.drop_column('notification_statistics', 'day_string') + op.create_unique_constraint('uix_service_to_day', 'notification_statistics', columns=['service_id', 'day']) + + ### end Alembic commands ### + + +def downgrade(): + ### commands auto generated by Alembic - please adjust! ### + op.drop_index(op.f('ix_notification_statistics_day'), table_name='notification_statistics') + op.drop_constraint('uix_service_to_day', 'notification_statistics') + + op.alter_column('notification_statistics', 'day', new_column_name='day_date') + op.add_column('notification_statistics', sa.Column('day', sa.String(), nullable=True)) + + op.get_bind() + op.execute("UPDATE notification_statistics ns1 SET day = (SELECT to_char(day_date, 'YYYY-MM-DD') FROM notification_statistics ns2 WHERE ns1.id = ns2.id)") + + op.alter_column('notification_statistics', 'day', nullable=False) + op.drop_column('notification_statistics', 'day_date') + op.create_unique_constraint('uix_service_to_day', 'notification_statistics', columns=['service_id', 'day']) + + ### end Alembic commands ### diff --git a/tests/app/dao/test_notification_dao.py b/tests/app/dao/test_notification_dao.py index a2acfd43b..2331c8e77 100644 --- a/tests/app/dao/test_notification_dao.py +++ b/tests/app/dao/test_notification_dao.py @@ -161,7 +161,7 @@ def test_should_be_able_to_get_statistics_for_a_service(sample_template): assert stats[0].sms_requested == 1 assert stats[0].sms_delivered == 0 assert stats[0].sms_failed == 0 - assert stats[0].day == notification.created_at.strftime(DATE_FORMAT) + assert stats[0].day == notification.created_at.date() assert stats[0].service_id == notification.service_id assert stats[0].emails_requested == 0 assert stats[0].emails_delivered == 0 @@ -182,7 +182,7 @@ def test_should_be_able_to_get_statistics_for_a_service_for_a_day(sample_templat notification = Notification(**data) dao_create_notification(notification, sample_template.template_type) stat = dao_get_notification_statistics_for_service_and_day( - sample_template.service.id, now.strftime(DATE_FORMAT) + sample_template.service.id, now.date() ) assert stat.emails_requested == 0 assert stat.emails_failed == 0 @@ -190,7 +190,7 @@ def test_should_be_able_to_get_statistics_for_a_service_for_a_day(sample_templat assert stat.sms_requested == 1 assert stat.sms_failed == 0 assert stat.sms_delivered == 0 - assert stat.day == notification.created_at.strftime(DATE_FORMAT) + assert stat.day == notification.created_at.date() assert stat.service_id == notification.service_id @@ -208,7 +208,7 @@ def test_should_return_none_if_no_statistics_for_a_service_for_a_day(sample_temp notification = Notification(**data) dao_create_notification(notification, sample_template.template_type) assert not dao_get_notification_statistics_for_service_and_day( - sample_template.service.id, (datetime.utcnow() - timedelta(days=1)).strftime(DATE_FORMAT) + sample_template.service.id, (datetime.utcnow() - timedelta(days=1)).date() ) @@ -267,13 +267,13 @@ def test_should_be_able_to_get_all_statistics_for_a_service_for_several_days(sam assert len(stats) == 3 assert stats[0].emails_requested == 0 assert stats[0].sms_requested == 1 - assert stats[0].day == today.strftime(DATE_FORMAT) + assert stats[0].day == today.date() assert stats[1].emails_requested == 0 assert stats[1].sms_requested == 1 - assert stats[1].day == yesterday.strftime(DATE_FORMAT) + assert stats[1].day == yesterday.date() assert stats[2].emails_requested == 0 assert stats[2].sms_requested == 1 - assert stats[2].day == two_days_ago.strftime(DATE_FORMAT) + assert stats[2].day == two_days_ago.date() def test_should_be_empty_list_if_no_statistics_for_a_service(sample_service): @@ -314,10 +314,10 @@ def test_should_be_able_to_get_all_statistics_for_a_service_for_several_days_pre assert len(stats) == 2 assert stats[0].emails_requested == 0 assert stats[0].sms_requested == 1 - assert stats[0].day == today.strftime(DATE_FORMAT) + assert stats[0].day == today.date() assert stats[1].emails_requested == 0 assert stats[1].sms_requested == 1 - assert stats[1].day == seven_days_ago.strftime(DATE_FORMAT) + assert stats[1].day == seven_days_ago.date() def test_save_notification_creates_sms_and_template_stats(sample_template, sample_job): @@ -431,7 +431,7 @@ def test_save_notification_handles_midnight_properly(sample_template, sample_job NotificationStatistics.service_id == sample_template.service.id ).first() - assert stats.day == '2016-01-01' + assert stats.day == date(2016, 1, 1) @freeze_time("2016-01-01 23:59:59.999999") @@ -456,7 +456,7 @@ def test_save_notification_handles_just_before_midnight_properly(sample_template NotificationStatistics.service_id == sample_template.service.id ).first() - assert stats.day == '2016-01-01' + assert stats.day == date(2016, 1, 1) def test_save_notification_and_increment_email_stats(sample_email_template, sample_job):