Gold Tables Consolidation
Overview
The gold data directory has been consolidated from 86 files to 21 files (75% reduction) to simplify HuggingFace deployment and make the codebase easier to manage.
Changes Made
Before (86 files)
data/gold/
├── national/
│ ├── bill_map_aggregate.parquet
│ ├── events.parquet
│ ├── nonprofits_financials.parquet
│ ├── nonprofits_locations.parquet
│ ├── nonprofits_organizations.parquet
│ └── nonprofits_programs.parquet
├── reference/
│ ├── causes_everyorg_causes.parquet
│ ├── causes_ntee_codes
│ ├── domains_gsa_domains.parquet
│ ├── jurisdictions_cities.parquet
│ ├── jurisdictions_counties.parquet
│ ├── jurisdictions_school_districts.parquet
│ ├── jurisdictions_townships.parquet
│ └── zip_county_mapping.parquet
└── states/
├── AL/ (16 files)
├── GA/ (16 files)
├── IN/ (partial)
├── MA/ (17 files)
├── WA/ (16 files)
└── WI/ (6 files)
After (21 files)
data/gold/
├── bills_bill_actions.parquet (52 MB)
├── bills_bill_sponsorships.parquet (39 MB)
├── bills_bills.parquet (15 MB)
├── bill_map_aggregate.parquet (142 KB)
├── causes_everyorg_causes.parquet (11 KB)
├── causes_ntee_codes (11 KB)
├── contacts_local_officials.parquet (15 KB)
├── contact_official.parquet (461 KB)
├── domains_gsa_domains.parquet (596 KB)
├── events_documents.parquet (366 MB)
├── events_participants.parquet (808 KB)
├── events.parquet (1.8 MB)
├── jurisdictions_cities.parquet (2.0 MB)
├── jurisdictions_counties.parquet (244 KB)
├── jurisdictions_school_districts.parquet (926 KB)
├── jurisdictions_townships.parquet (2.4 MB)
├── nonprofits_financials.parquet (77 MB)
├── nonprofits_locations.parquet (86 MB)
├── nonprofits_organizations.parquet (134 MB)
├── nonprofits_programs.parquet (65 MB)
└── zip_county_mapping.parquet (323 KB)
Key Changes
1. State Data Consolidation
Before:
- Separate files per state:
data/gold/states/AL/bills_bills.parquet,data/gold/states/GA/bills_bills.parquet, etc. - Difficult to query across states
- Many small duplicate files
After:
- Single consolidated file:
data/gold/bills_bills.parquet - Contains
statecolumn for filtering - Easy to query across all states
2. API Code Updates
Old pattern:
for st in states:
parquet_path = Path(f"data/gold/states/{st}/bills_bills.parquet")
df = pd.read_parquet(parquet_path)
# process...
New pattern:
parquet_path = Path("data/gold/bills_bills.parquet")
df = pd.read_parquet(parquet_path)
if state:
df = df[df['state'] == state]
Files updated:
api/main.py- Updated opportunities endpoint to use consolidated billsapi/routes/stats.py- Updated stats endpoints for nonprofits, events, contacts
3. File Size Compliance
All files are under HuggingFace's 500MB recommended limit:
- Largest file:
events_documents.parquetat 366 MB - Total data size: ~840 MB
Benefits
- Simpler deployment - Fewer files to upload to HuggingFace
- Better queries - Can query across all states in single operation
- Easier maintenance - One file per table type instead of 5+ copies
- Cleaner codebase - Less path juggling in API code
- Faster reads - Read once instead of multiple times for multi-state queries
Scripts
Consolidation Script
# Consolidate state-partitioned files (already done)
python scripts/data/rebuild_consolidated_gold.py
# Dry run to preview
python scripts/data/rebuild_consolidated_gold.py --dry-run
Upload to HuggingFace
# Upload all consolidated files
python -m hosting.huggingface gold
# Upload specific file
python -m hosting.huggingface gold --file bills_bills.parquet
# Test with row limit
python -m hosting.huggingface gold --max-rows 1000
# Skip large files
python -m hosting.huggingface gold --skip-large
Querying Consolidated Data
Python
import pandas as pd
# Load consolidated bills data
df = pd.read_parquet('data/gold/bills_bills.parquet')
# Filter by state
ma_bills = df[df['state'] == 'MA']
# Query across multiple states
southern_bills = df[df['state'].isin(['AL', 'GA'])]
DuckDB
-- Query all bills
SELECT * FROM read_parquet('data/gold/bills_bills.parquet');
-- Filter by state
SELECT * FROM read_parquet('data/gold/bills_bills.parquet')
WHERE state = 'MA';
-- Aggregate across states
SELECT state, COUNT(*) as bill_count
FROM read_parquet('data/gold/bills_bills.parquet')
GROUP BY state;
Backup
The original state-partitioned structure is backed up in data/gold_old/ (not committed to git).
To restore if needed:
mv data/gold data/gold_consolidated
mv data/gold_old data/gold
Migration Notes
- ✅ All files include
statecolumn where applicable - ✅ National and reference tables copied as-is
- ✅ API code updated to use consolidated files
- ⚠️ Example scripts in
examples/andscripts/enrichment/still reference old paths (low priority - for local dev only) - ⚠️ Documentation files still show old paths (needs update)
Next Steps
- ✅ Test API endpoints with consolidated data
- ⏳ Upload consolidated files to HuggingFace
- ⏳ Update documentation to reflect new structure
- ⏳ Update example scripts to use consolidated files
- ⏳ Deploy to production and verify