Migrate an application's data access layer from one database schema to another. Use when tables are renamed, consolidated, split, or columns change — and the app's queries, mappings, and abstraction layer must be updated without data loss. Read-only against the database.
Systematically migrate an application from a legacy database schema to a new schema with zero data loss and full functional parity.
CREATE, ALTER, INSERT, UPDATE, DELETE) against the database. All analysis is SELECT-only.Table.Column.github/plans/temp_migration_scratchpad.md to preserve state across reasoning steps.Build a complete picture of old and new schemas. Produce the Schema Manifest — the single source of truth for the migration.
Collect Legacy Schema DDL
CREATE TABLE statements for all legacy tables (from schema files, INFORMATION_SCHEMA, or DDL scripts).env entries, config files)Collect Target Schema DDL
CREATE TABLE statements for all new/consolidated tablesAudit the Abstraction Layer
column_mappings.yaml, .env, config modules)queries.yaml, .sql files)Produce the Mapping Manifest
## Schema Mapping Manifest
### Table Mapping
| Legacy Table | Target Table | Notes |
|-------------|-------------|-------|
| OldTableA | NewTable1 | Merged with OldTableB |
### Column Mapping
| Legacy Table | Legacy Column | Type | Target Table | Target Column | Type | Transform |
|-------------|--------------|------|-------------|--------------|------|-----------|
| OldTableA | user_name | NVARCHAR(100) | NewTable1 | UserFullName | NVARCHAR(200) | Direct |
| OldTableA | status_code | INT | NewTable1 | Status | VARCHAR(20) | Map: 1='Active', 2='Inactive' |
### Gaps (Unmapped)
| Source | Column | Issue |
|--------|--------|-------|
| OldTableC | legacy_flag | No equivalent in target schema |
| File: results/*.json | summary_json | Verify if present in CallTranscript table |
Output: Schema Mapping Manifest (table in the migration report)
Rewrite every application query against the new schema. No aliases — direct Table.Column references only.
Inventory Current Queries
Translate Each Query
CAST, CASE WHEN) where the new schema uses a different data typeDocument Translation
### Query: [query_name]
**Old Query:**
```sql
SELECT col_a, col_b FROM OldTable WHERE col_c = ?
New Query:
SELECT NewTable.ColA, NewTable.ColB FROM NewTable WHERE NewTable.ColC = ?
Changes:
OldTable → NewTablecol_a → ColA (renamed)
4. **File Architecture Decision** (if applicable)
- If the app uses a monolithic query file, evaluate splitting into per-page/per-feature files
- Compare `.yaml` vs `.sql` for query storage:
| Format | Pros | Cons |
|--------|------|------|
| `.yaml` | Structured metadata (tags, descriptions), easy Python parsing | No SQL syntax highlighting, IDE support limited |
| `.sql` | Full IDE support, syntax checking, execution in DB tools | Needs a loader; metadata requires naming conventions or comments |
- Recommend based on the project's existing patterns and tooling
**Output**: Translated Query Library + File Architecture Recommendation
---
## Phase 3: Parity Testing
### Objective
Prove that the new queries return the same data as the old queries. Evidence-based — not theoretical.
### Actions
1. **Run Old Queries** — Execute each legacy query and capture:
- Row count
- Column names and types
- Sample rows (5–10 representative rows)
- Aggregates where applicable (SUM, COUNT, DISTINCT)
2. **Run New Queries** — Execute each translated query against the new schema and capture the same metrics
3. **Compare Results**
```markdown
### Parity Report: [query_name]
| Metric | Old Query | New Query | Match |
|--------|-----------|-----------|-------|
| Row count | 1,247 | 1,247 | ✅ |
| Columns | 8 | 8 | ✅ |
| Sample hash | abc123 | abc123 | ✅ |
**Data Type Check:**
| Column | Old Type | New Type | Compatible |
|--------|---------|---------|------------|
| created_at | DATETIME | DATETIMEOFFSET | ⚠️ App must handle offset |
Output: Parity Report per query (pass/fail with evidence)
Update the application's configuration and mapping layer to reflect the new schema.
Update Column Mappings — Produce the new version of column_mappings.yaml (or equivalent) reflecting target table/column names
Update Environment Config — Produce the new .env variable values (table names, schema names)
Update Query Files — Produce the new query file(s) using the translated queries from Phase 2
Trace Application Code Impact
no change needed | config-only change | code change required### Impact Analysis
| File | Current Reference | Change Type | Details |
|------|------------------|-------------|---------|
| services/data_loader.py | OldTable via .env | Config-only | Update .env mapping |
| pages/home.py | col_a in display | Code change | Rename to ColA |
| models/complaint.py | OldTable.status_code (INT) | Code change | Now VARCHAR, update parsing |
Output: Updated config files + application impact matrix
Produce a single, comprehensive document suitable for use as an Implementation Plan. This document must be complete enough that a developer can execute the migration with zero ambiguity.
# Schema Migration Report
## Executive Summary
- Source: [N] legacy tables → Target: [M] consolidated tables
- Total queries migrated: [count]
- Parity status: [all pass / N failures]
- Gaps identified: [count]
## 1. Schema Mapping Manifest
[From Phase 1]
## 2. Translated Query Library
[From Phase 2, grouped by page/feature]
## 3. Parity Test Results
[From Phase 3, pass/fail per query with evidence]
## 4. Abstraction Layer Changes
[From Phase 4 — updated YAML, .env, config diffs]
## 5. Application Impact Matrix
[From Phase 4 — file-by-file change list]
## 6. File Architecture Recommendation
[From Phase 2 — split strategy and format decision]
## 7. Edge-Case Registry
[Every risk identified during analysis]
| # | Risk | Severity | Mitigation |
|---|------|----------|------------|
| 1 | DATETIME → DATETIMEOFFSET | Medium | Add .replace(tzinfo=None) in Python |
| 2 | Nullable column X now NOT NULL | High | Add default value in query |
## 8. Migration Execution Checklist
- [ ] Column mappings updated
- [ ] Environment config updated
- [ ] Query files updated and tested
- [ ] Application code changes identified and assigned
- [ ] All parity tests passing
- [ ] Edge cases mitigated
- [ ] Rollback plan documented
Place the final report at the path specified by the user (default: .github/plans/backlog/migration_report.md).