from datetime import datetime from sqlalchemy.dialects.postgresql import insert from app import db from app.dao.dao_utils import autocommit from app.models import DailySortedLetter def dao_get_daily_sorted_letter_by_billing_day(billing_day): return DailySortedLetter.query.filter_by( billing_day=billing_day ).first() @autocommit def dao_create_or_update_daily_sorted_letter(new_daily_sorted_letter): ''' This uses the Postgres upsert to avoid race conditions when two threads try and insert at the same row. The excluded object refers to values that we tried to insert but were rejected. http://docs.sqlalchemy.org/en/latest/dialects/postgresql.html#insert-on-conflict-upsert ''' table = DailySortedLetter.__table__ stmt = insert(table).values( billing_day=new_daily_sorted_letter.billing_day, file_name=new_daily_sorted_letter.file_name, unsorted_count=new_daily_sorted_letter.unsorted_count, sorted_count=new_daily_sorted_letter.sorted_count) stmt = stmt.on_conflict_do_update( index_elements=[table.c.billing_day, table.c.file_name], set_={ 'unsorted_count': stmt.excluded.unsorted_count, 'sorted_count': stmt.excluded.sorted_count, 'updated_at': datetime.utcnow() } ) db.session.connection().execute(stmt)