migrating-code

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Migrating Code

代码迁移

Core Principles

核心原则

  1. Never break production - Backward compatible until fully rolled out
  2. Small, reversible steps - Each step independently deployable
  3. Test at every stage - Before, during, and after
  4. Have rollback ready - Always
  1. 绝不破坏生产环境 - 在完全部署完成前保持向后兼容
  2. 小步推进、可回滚 - 每个步骤均可独立部署
  3. 全程测试 - 迁移前、迁移中、迁移后均需测试
  4. 准备回滚方案 - 始终做好准备

Migration Checklist

迁移检查清单

- [ ] Pre-Migration: Read changelog, identify breaking changes, ensure test coverage
- [ ] During: Small steps, test each, monitor errors, rollback ready
- [ ] Post: Verify tests, check metrics, remove scaffolding, update docs
- [ ] 迁移前:阅读更新日志,识别破坏性变更,确保测试覆盖率
- [ ] 迁移中:小步推进,逐个测试,监控错误,准备回滚
- [ ] 迁移后:验证测试结果,检查指标,移除脚手架代码,更新文档

Database Schema

数据库 Schema

Safe Patterns

安全模式

OperationPattern
Add columnAdd nullable first → backfill → add constraints
Remove columnStop writes → deploy code that doesn't read → drop column
Rename columnAdd new → dual-write → backfill → switch reads → drop old
Change typeNew column → dual-write → migrate in batches → switch → drop
Never: Add NOT NULL without defaults to tables with data.
操作模式
添加列先添加可为空的列 → 回填数据 → 添加约束
删除列停止写入 → 部署不再读取该列的代码 → 删除列
重命名列添加新列 → 双写数据 → 回填数据 → 切换读取新列 → 删除旧列
变更类型添加新列 → 双写数据 → 分批迁移数据 → 切换读取新列 → 删除旧列
注意: 切勿向已有数据的表添加无默认值的非空列。

API Migrations

API 迁移

Deprecation Process

弃用流程

  1. Add deprecation warnings to old endpoints
  2. Document migration path
  3. Set and communicate sunset date
  4. Monitor usage
  5. Remove after usage drops
json
{
  "data": {},
  "_warnings": [{
    "code": "DEPRECATED_ENDPOINT",
    "message": "Use /api/v2/users instead",
    "sunset": "2025-06-01"
  }]
}
  1. 向旧端点添加弃用警告
  2. 编写迁移路径文档
  3. 设置并告知停用日期
  4. 监控旧端点的使用情况
  5. 使用量下降后移除旧端点
json
{
  "data": {},
  "_warnings": [{
    "code": "DEPRECATED_ENDPOINT",
    "message": "请使用 /api/v2/users",
    "sunset": "2025-06-01"
  }]
}

Framework Upgrades

框架升级

  1. Upgrade to latest minor first - Get deprecation warnings
  2. Fix warnings - Before major upgrade
  3. One major at a time - Don't batch
  4. Test after each step
  1. 先升级到最新小版本 - 获取弃用警告
  2. 修复警告 - 在进行大版本升级前完成
  3. 每次仅升级一个大版本 - 不要批量升级
  4. 每步升级后测试

Adapter Pattern for Library Swaps

库替换的适配器模式

typescript
// Wrap library usage
// lib/date.ts
import moment from 'moment';
export const formatDate = (date: Date, format: string) =>
  moment(date).format(format);

// Migration: just change the adapter
import { format } from 'date-fns';
export const formatDate = (date: Date, fmt: string) =>
  format(date, fmt);
typescript
// 封装库的使用
// lib/date.ts
import moment from 'moment';
export const formatDate = (date: Date, format: string) =>
  moment(date).format(format);

// 迁移:只需修改适配器
import { format } from 'date-fns';
export const formatDate = (date: Date, fmt: string) =>
  format(date, fmt);

Gradual Rollout

逐步部署

Use feature flags:
typescript
if (featureFlags.useNewSystem) {
  return newService.process(order);
} else {
  return legacyService.process(order);
}
Roll out: 1% → 10% → 50% → 100% → remove flag
使用特性标志:
typescript
if (featureFlags.useNewSystem) {
  return newService.process(order);
} else {
  return legacyService.process(order);
}
部署步骤:1% → 10% → 50% → 100% → 移除特性标志

Common Pitfalls

常见陷阱

Avoid:
  • Big bang migrations
  • No rollback plans
  • Skipping dual-write phase
  • Single large data transactions
  • Removing old code before new is proven
Do:
  • Small, reversible steps
  • Test rollback procedures
  • Batch large data migrations
  • Keep old paths until new verified
需避免:
  • 大爆炸式迁移
  • 无回滚计划
  • 跳过双写阶段
  • 单个大型数据事务
  • 在新方案验证通过前移除旧代码
建议:
  • 小步推进、可回滚的步骤
  • 测试回滚流程
  • 分批处理大型数据迁移
  • 在新方案验证通过前保留旧路径