Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Plan and execute database schema migrations safely with rollback strategies and zero-downtime deployment patterns.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
references/details.md
1# database-migration — additional patterns and templates23## Zero-Downtime Migrations45### Blue-Green Deployment Strategy67```javascript8// Phase 1: Make changes backward compatible9module.exports = {10up: async (queryInterface, Sequelize) => {11// Add new column (both old and new code can work)12await queryInterface.addColumn("users", "email_new", {13type: Sequelize.STRING,14});15},16};1718// Phase 2: Deploy code that writes to both columns1920// Phase 3: Backfill data21module.exports = {22up: async (queryInterface) => {23await queryInterface.sequelize.query(`24UPDATE users25SET email_new = email26WHERE email_new IS NULL27`);28},29};3031// Phase 4: Deploy code that reads from new column3233// Phase 5: Remove old column34module.exports = {35up: async (queryInterface) => {36await queryInterface.removeColumn("users", "email");37},38};39```4041## Cross-Database Migrations4243### PostgreSQL to MySQL4445```javascript46// Handle differences47module.exports = {48up: async (queryInterface, Sequelize) => {49const dialectName = queryInterface.sequelize.getDialect();5051if (dialectName === "mysql") {52await queryInterface.createTable("users", {53id: {54type: Sequelize.INTEGER,55primaryKey: true,56autoIncrement: true,57},58data: {59type: Sequelize.JSON, // MySQL JSON type60},61});62} else if (dialectName === "postgres") {63await queryInterface.createTable("users", {64id: {65type: Sequelize.INTEGER,66primaryKey: true,67autoIncrement: true,68},69data: {70type: Sequelize.JSONB, // PostgreSQL JSONB type71},72});73}74},75};76```77