The migration script failed at row 12, and the logs pointed to the same culprit: no column to hold the data.
Adding a new column seems simple. In production, it’s not. Schema changes can lock tables, block queries, and cascade into downtime. The difference between clean deployment and chaos is knowing when and how to create that new column.
Every database engine handles this operation differently. In PostgreSQL, adding a nullable column with a default is safe if the default is not computed. In MySQL, the table may copy in place for certain storage engines, increasing migration time. In distributed systems, schema changes must propagate across shards without leaving queries in an inconsistent state.
Plan the change. Write an explicit migration. Test it against real data size, not just fixtures. Avoid altering hot tables during peak load. When you must change defaults or set NOT NULL constraints, break the process into steps: create the column, backfill data in batches, then enforce constraints. This reduces lock time and avoids blocking writes.