06/05 Optimize app
This commit is contained in:
@@ -217,12 +217,6 @@ def sync_transactions(item):
|
||||
return added, modified, removed, cursor
|
||||
|
||||
|
||||
def build_category_map():
|
||||
from app.models.category import Category
|
||||
cats = Category.query.filter_by(is_active=True).all()
|
||||
return {c.name: c.id for c in cats}
|
||||
|
||||
|
||||
def _map_plaid_category(plaid_cats, txn_type):
|
||||
"""Map Plaid category array to a PFM category name."""
|
||||
if not plaid_cats:
|
||||
@@ -292,6 +286,7 @@ def sync_preview(item):
|
||||
added, _modified, _removed, next_cursor = sync_transactions(item)
|
||||
|
||||
# Build maps
|
||||
from app.services.bank_import_service import build_category_map
|
||||
plaid_accounts = PlaidAccount.query.filter_by(item_id=item.id, is_active=True).all()
|
||||
plaid_account_map = {pa.plaid_account_id: pa.pfm_account_id for pa in plaid_accounts}
|
||||
cat_map = build_category_map()
|
||||
@@ -324,9 +319,17 @@ def import_transactions(parsed_txns, next_cursor, item):
|
||||
affected_accounts = set()
|
||||
plaid_account_ids_synced = set()
|
||||
|
||||
# Batch duplicate check — one IN query instead of one LIKE per transaction
|
||||
candidate_notes = {p['notes'] for p in parsed_txns} # 'Plaid:{id}'
|
||||
existing_notes = {
|
||||
r[0] for r in
|
||||
db.session.query(Transaction.notes)
|
||||
.filter(Transaction.notes.in_(candidate_notes))
|
||||
.all()
|
||||
} if candidate_notes else set()
|
||||
|
||||
for p in parsed_txns:
|
||||
pid = p['plaid_id']
|
||||
if Transaction.query.filter(Transaction.notes.like(f'%Plaid:{pid}%')).first():
|
||||
if p['notes'] in existing_notes:
|
||||
skipped += 1
|
||||
continue
|
||||
|
||||
@@ -344,18 +347,13 @@ def import_transactions(parsed_txns, next_cursor, item):
|
||||
plaid_account_ids_synced.add(p['plaid_account_id'])
|
||||
imported += 1
|
||||
|
||||
db.session.commit()
|
||||
|
||||
# Advance cursor
|
||||
# Single commit — transactions + cursor + metadata together
|
||||
item.cursor = next_cursor
|
||||
item.last_synced_at = datetime.utcnow()
|
||||
|
||||
# Update last_sync_date per PlaidAccount
|
||||
today = date.today()
|
||||
for pa in PlaidAccount.query.filter_by(item_id=item.id, is_active=True).all():
|
||||
if pa.plaid_account_id in plaid_account_ids_synced:
|
||||
pa.last_sync_date = today
|
||||
|
||||
db.session.commit()
|
||||
|
||||
# Refresh balances for mapped accounts
|
||||
@@ -441,6 +439,7 @@ def auto_sync_item(item):
|
||||
|
||||
added, modified, removed, next_cursor = sync_transactions(item)
|
||||
|
||||
from app.services.bank_import_service import build_category_map
|
||||
plaid_accounts = PlaidAccount.query.filter_by(item_id=item.id, is_active=True).all()
|
||||
plaid_account_map = {pa.plaid_account_id: pa.pfm_account_id for pa in plaid_accounts}
|
||||
cat_map = build_category_map()
|
||||
@@ -456,17 +455,14 @@ def auto_sync_item(item):
|
||||
|
||||
imported, skipped = import_transactions(parsed, next_cursor, item)
|
||||
|
||||
# Remove transactions that Plaid says are gone (e.g. pending dropped)
|
||||
# Remove transactions that Plaid says are gone — batch lookup
|
||||
removed_count = 0
|
||||
if removed:
|
||||
for r in removed:
|
||||
tid = r.get('transaction_id', '')
|
||||
txn = Transaction.query.filter(
|
||||
Transaction.notes.like(f'%Plaid:{tid}%')
|
||||
).first()
|
||||
if txn:
|
||||
db.session.delete(txn)
|
||||
removed_count += 1
|
||||
remove_notes = {f'Plaid:{r.get("transaction_id", "")}' for r in removed if r.get('transaction_id')}
|
||||
txns_to_delete = Transaction.query.filter(Transaction.notes.in_(remove_notes)).all()
|
||||
for txn in txns_to_delete:
|
||||
db.session.delete(txn)
|
||||
removed_count += 1
|
||||
if removed_count:
|
||||
db.session.commit()
|
||||
log.info('[plaid] auto_sync removed %d transaction(s) for item %s',
|
||||
|
||||
Reference in New Issue
Block a user