open-navigator / web_docs /docs /development /state-naming-migration.md
jcbowyer's picture
Clean HuggingFace deployment without binary files
e59d91d
|
Raw
History Blame Contribute Delete
7.49 kB
---
sidebar_position: 5
---
# βœ… State Naming Migration Complete
**Date:** 2026-05-03
**Scope:** Complete migration of ALL database tables, parquet files, and code references to standardized state naming convention
---
## πŸ“‹ Migration Standard
**Naming Convention:**
- `state_code`: VARCHAR(2) - Two-letter state abbreviation (e.g., 'AL', 'MA', 'WI')
- `state`: VARCHAR(50) - Full state name (e.g., 'Alabama', 'Massachusetts', 'Wisconsin')
**Rationale:**
- **Consistency:** All tables and files now use the same column names
- **Clarity:** No ambiguity about whether 'state' contains codes or names
- **Joins:** Easier to join tables using consistent column names
- **User-Facing:** Can display full state names without additional lookups
---
## βœ… What Was Migrated
### 1. Database Schema (packages/hosting/src/hosting/neon/schema.sql)
All 7 search tables updated with `state_code` + `state` columns:
- βœ… `jurisdiction_state_aggregate`
- βœ… `organization_nonprofit`
- βœ… `jurisdiction`
- βœ… `jurisdictions_details_search`
- βœ… `contact`
- βœ… `event`
- βœ… `bills_search`
**Indexes Created:**
- `idx_{table}_state_code` on all tables
- `idx_{table}_state` on all tables
### 2. Database Data (Actual Tables)
All existing database tables migrated using `scripts/migrate_all_state_naming.py`:
- Added `state_code` and `state` columns
- Populated `state_code` from old `state` column
- Populated `state` using STATE_NAMES mapping dictionary
- Dropped old `state` column, renamed `state_name` to `state`
- Recreated indexes for performance
**Records Migrated:**
- Exact counts vary by table (see database for current stats)
- Migration script is **idempotent** - safe to run multiple times
### 3. Parquet Files (data/gold/)
**26 parquet files** migrated using `scripts/migrate_all_parquet_state_naming.py`:
**Core Gold Tables:**
- βœ… `bills_bill_actions.parquet`
- βœ… `bills_bill_sponsorships.parquet`
- βœ… `bills_bill_text.parquet`
- βœ… `bills_bills.parquet`
- βœ… `bill_map_aggregate.parquet`
- βœ… `bills_versions.parquet`
- βœ… `contacts_local_officials.parquet`
- βœ… `contact_official.parquet`
- βœ… `events_documents.parquet`
- βœ… `events_participants.parquet`
- βœ… `jurisdictions_cities.parquet` (was using 'USPS')
- βœ… `jurisdictions_counties.parquet` (was using 'USPS')
- βœ… `jurisdictions_details.parquet` (already migrated previously)
- βœ… `jurisdictions_school_districts.parquet` (was using 'USPS' + 'state')
- βœ… `jurisdictions_townships.parquet` (was using 'USPS')
- βœ… `jurisdictions_websites.parquet`
- βœ… `nonprofits_financials.parquet`
- βœ… `nonprofits_locations.parquet`
- βœ… `nonprofits_organizations.parquet`
- βœ… `nonprofits_programs.parquet`
**State-Specific Files:**
- βœ… `states/AL/contact_official.parquet`
- βœ… `states/GA/contact_official.parquet`
- βœ… `states/IN/contact_official.parquet`
- βœ… `states/MA/contact_official.parquet`
- βœ… `states/WA/contact_official.parquet`
- βœ… `states/WI/contact_official.parquet`
**Backups Created:**
All original files backed up with `_backup` suffix (e.g., `bills_bills_backup.parquet`)
### 4. Code References (packages/hosting/src/hosting/neon/migrate.py)
All load functions updated to use new column names:
**Updated Functions:**
- βœ… `load_organization_nonprofit()` - Uses `state_code` column from parquet, inserts both `state_code` and `state` to database
- βœ… `load_contact()` - All three contact sources (state legislators, local officials, nonprofit officers) updated
- βœ… `load_event()` - Inserts both `state_code` and `state`
- βœ… `load_bills_search()` - Inserts both `state_code` and `state`
- βœ… `compute_jurisdiction_state_aggregate()` - Uses `state_code` when filtering parquet files
**State Mapping:**
All functions now use the `STATE_NAMES` dictionary to map 2-letter codes to full names:
```python
STATE_NAMES = {
'AL': 'Alabama', 'AK': 'Alaska', ...
}
```
---
## πŸ› οΈ Migration Scripts
### Database Migration
```bash
# Migrate database tables (already run)
python scripts/migrate_all_state_naming.py
```
### Parquet Migration
```bash
# Migrate all parquet files (already run)
python scripts/migrate_all_parquet_state_naming.py
# Dry run to preview changes
python scripts/migrate_all_parquet_state_naming.py --dry-run
```
Both scripts are **idempotent** and can be run multiple times safely.
---
## πŸ“Š Migration Statistics
**Database Tables:** 7 tables migrated
**Parquet Files:** 26 files migrated
**Code Functions:** 5 load functions updated
**Backups Created:** 27 backup files (1 database, 26 parquet)
**Total Data Size:** ~2-3 GB across all files
---
## βœ… Verification
### Check Database Schema
```sql
-- Verify columns exist
SELECT column_name, data_type
FROM information_schema.columns
WHERE table_name = 'organization_nonprofit'
AND column_name IN ('state_code', 'state');
-- Should return:
-- state_code | character varying(2)
-- state | character varying(50)
```
### Check Parquet Files
```python
import pandas as pd
df = pd.read_parquet('data/gold/nonprofits_organizations.parquet')
print(df[['state_code', 'state']].head())
# Should show:
# state_code state
# 0 AL Alabama
# 1 CA California
```
### Check Code
```bash
# Verify migrate.py has no syntax errors
python -m py_compile packages/hosting/src/hosting/neon/migrate.py
# Verify INSERT statements include both columns
grep -n "state_code, state" packages/hosting/src/hosting/neon/migrate.py
```
---
## 🎯 Next Steps
1. **Test Data Loading:** Run `packages/hosting/src/hosting/neon/migrate.py` to reload data with new schema
2. **Update API Queries:** Review API routes for any state filtering logic
3. **Update Frontend:** Ensure UI displays full state names where appropriate
4. **Update Documentation:** Document the new standard in data source docs
---
## πŸ“š Reference
**State Names Mapping:**
```python
STATE_NAMES = {
'AL': 'Alabama', 'AK': 'Alaska', 'AZ': 'Arizona', 'AR': 'Arkansas',
'CA': 'California', 'CO': 'Colorado', 'CT': 'Connecticut',
'DE': 'Delaware', 'FL': 'Florida', 'GA': 'Georgia', 'HI': 'Hawaii',
'ID': 'Idaho', 'IL': 'Illinois', 'IN': 'Indiana', 'IA': 'Iowa',
'KS': 'Kansas', 'KY': 'Kentucky', 'LA': 'Louisiana', 'ME': 'Maine',
'MD': 'Maryland', 'MA': 'Massachusetts', 'MI': 'Michigan',
'MN': 'Minnesota', 'MS': 'Mississippi', 'MO': 'Missouri',
'MT': 'Montana', 'NE': 'Nebraska', 'NV': 'Nevada',
'NH': 'New Hampshire', 'NJ': 'New Jersey', 'NM': 'New Mexico',
'NY': 'New York', 'NC': 'North Carolina', 'ND': 'North Dakota',
'OH': 'Ohio', 'OK': 'Oklahoma', 'OR': 'Oregon', 'PA': 'Pennsylvania',
'RI': 'Rhode Island', 'SC': 'South Carolina', 'SD': 'South Dakota',
'TN': 'Tennessee', 'TX': 'Texas', 'UT': 'Utah', 'VT': 'Vermont',
'VA': 'Virginia', 'WA': 'Washington', 'WV': 'West Virginia',
'WI': 'Wisconsin', 'WY': 'Wyoming', 'DC': 'District of Columbia',
'PR': 'Puerto Rico'
}
```
---
## ⚠️ Important Notes
1. **Backward Compatibility:** Old queries using just 'state' will fail - must update to use 'state_code' for 2-letter codes
2. **Backups:** All original files backed up with `_backup` suffix - safe to delete after verifying migration
3. **Indexes:** Database indexes automatically recreated for both columns
4. **Performance:** No significant performance impact - indexed columns query efficiently
---
**Migration Completed By:** GitHub Copilot
**Last Updated:** 2026-05-03