Doctrine is smart enough to know that we should rename the column instead of
dropping the old column and adding a new one.

Dangerous Deploy Ahead!

Great! Let's deploy! Right!? Sure... if you want to take your site down for a minute
or two! Can you see the problem? If we deploy now, this migration will run... and
about 1 minute later, the deploy will finish and the new code will be used. The
problem is during that period. As soon as this migration executes, the image
column will be gone... but the live site will still try to use it! That's a huge
problem.

Nope, we need to be smarter: we need to write safe migrations. Here's the idea:
only write migrations that add new things & never write migrations that remove
things... unless that thing is not being used at all by the live site.

Writing Safe Migrations

This creates a slightly different workflow... with two deploys. For the first
deploy, change the migration: ALTER TABLE video ADD poster:

39 lines app/DoctrineMigrations/Version20170927100553.php

... lines 1 - 10

classVersion20170927100553extendsAbstractMigration

{

/**

* @param Schema $schema

*/

publicfunctionup(Schema $schema)

{

// this up() migration is auto-generated, please modify it to your needs

$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on \'mysql\'.');

This time, when the image column is removed, the production code is already
not using it.

The Edge Case: Updated Data

There is still one edge-case problem. On the first deploy, we used an UPDATE
statement to set poster = image. That makes those columns identical:

39 lines app/DoctrineMigrations/Version20170927100553.php

... lines 1 - 10

classVersion20170927100553extendsAbstractMigration

{

... lines 13 - 15

publicfunctionup(Schema $schema)

{

... lines 18 - 22

$this->addSql('UPDATE video SET poster = image');

}

... lines 25 - 37

}

But, for then next few seconds, the production code is still using the old image
column. That's fine... unless people are making changes to its data! Any changes
made to image during this period will be lost when the new production code
stops reading that column.

If you have this problem, you're going to need to be a little bit more intelligent,
and potentially run another UPDATE statement immediately after the new code becomes
live.

Ok! Our final migration ran, the deploy finished and the site still works... with no
downtime.