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
metadata
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:

STATE_NAMES = {
    'AL': 'Alabama', 'AK': 'Alaska', ...
}

πŸ› οΈ Migration Scripts

Database Migration

# Migrate database tables (already run)
python scripts/migrate_all_state_naming.py

Parquet Migration

# 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

-- 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

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

# 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:

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