fix(members): link sponsors to bills and fix member search
- Poller now fetches bill detail on insert to get sponsor (list endpoint has no sponsor data) - Add backfill_sponsor_ids task + admin endpoint + UI button to fix the 1,616 existing bills with NULL sponsor_id - Member name search now matches both "Last, First" and "First Last" using split_part() on the stored name column; same fix applied to global search - Load Bill.sponsor relationship eagerly in get_member_bills to prevent MissingGreenlet error during Pydantic serialization - Remove .trim() on search onChange so spaces can be typed Authored-By: Jack Levy
This commit is contained in:
@@ -71,8 +71,14 @@ def poll_congress_bills(self):
|
||||
existing = db.get(Bill, bill_id)
|
||||
|
||||
if existing is None:
|
||||
# Upsert sponsor member if referenced
|
||||
sponsor_id = _sync_sponsor(db, bill_data)
|
||||
# Bill list endpoint has no sponsor data — fetch detail to get it
|
||||
try:
|
||||
detail = congress_api.get_bill_detail(
|
||||
current_congress, parsed["bill_type"], parsed["bill_number"]
|
||||
)
|
||||
sponsor_id = _sync_sponsor(db, detail.get("bill", {}))
|
||||
except Exception:
|
||||
sponsor_id = None
|
||||
parsed["sponsor_id"] = sponsor_id
|
||||
parsed["last_checked_at"] = datetime.now(timezone.utc)
|
||||
db.add(Bill(**parsed))
|
||||
@@ -165,6 +171,33 @@ def _sync_sponsor(db, bill_data: dict) -> str | None:
|
||||
return bioguide_id
|
||||
|
||||
|
||||
@celery_app.task(bind=True, name="app.workers.congress_poller.backfill_sponsor_ids")
|
||||
def backfill_sponsor_ids(self):
|
||||
"""Backfill sponsor_id for all bills where it is NULL by fetching bill detail from Congress.gov."""
|
||||
import time
|
||||
db = get_sync_db()
|
||||
try:
|
||||
bills = db.query(Bill).filter(Bill.sponsor_id.is_(None)).all()
|
||||
total = len(bills)
|
||||
updated = 0
|
||||
logger.info(f"Backfilling sponsors for {total} bills")
|
||||
for bill in bills:
|
||||
try:
|
||||
detail = congress_api.get_bill_detail(bill.congress_number, bill.bill_type, bill.bill_number)
|
||||
sponsor_id = _sync_sponsor(db, detail.get("bill", {}))
|
||||
if sponsor_id:
|
||||
bill.sponsor_id = sponsor_id
|
||||
db.commit()
|
||||
updated += 1
|
||||
except Exception as e:
|
||||
logger.warning(f"Could not backfill sponsor for {bill.bill_id}: {e}")
|
||||
time.sleep(0.1) # ~10 req/sec, well under Congress.gov 5000/hr limit
|
||||
logger.info(f"Sponsor backfill complete: {updated}/{total} updated")
|
||||
return {"total": total, "updated": updated}
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
|
||||
def _update_bill_if_changed(db, existing: Bill, parsed: dict) -> bool:
|
||||
"""Update bill fields if anything has changed. Returns True if updated."""
|
||||
changed = False
|
||||
|
||||
Reference in New Issue
Block a user