Migrações de banco de dados complexas com PHP / MySQL usando Phinx

Até agora, eu usei dbdeploy para fazer migrações de banco de dados com instruções MySQL. No entanto, o MySQL é muito inconveniente para realizar etapas de migração mais complexas, por exemplo, se você deseja migrar não apenas o esquema da tabela, mas também os dados. Considere a seguinte migração, em que os valores são codificados em uma matriz json:

Antes da migração (tabela user_links):
Cenário

Após a migração (tabela token_links):
Cenário

Felizmente, existe uma nova ferramenta incrível de migração de banco de dados chamada phinx . Suporta PHP, MySQL, composer e é fácil de integrar com phing .

Veja como realizei a migração acima (formatação ruim por causa do pouco espaço):

use Phinx\Migration\AbstractMigration;

/** */
class UserLinksToTokenLinks extends AbstractMigration
{
/**
* Migrate Up.

*/

public function up()
{
$this
->execute("
CREATE TABLE IF NOT EXISTS `token_links` (

`linkID` INT(11) unsigned NOT NULL AUTO_INCREMENT,

`token` VARCHAR(100) NOT NULL,

`actionPlugin` VARCHAR(32) NOT NULL,

`actionParams` TEXT NULL DEFAULT NULL,

PRIMARY KEY (`linkID`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

"
);

// userLinks to tokenLinks
$userLinks
= $this->fetchAll('SELECT * FROM user_links');
foreach ($userLinks as $userLink) {
$actionPlugin
= ucfirst($userLink['action']);
$actionParams
= array();
$actionParams
['UserID'] = $userLink['userID'];

if (isset($userLink['userSurveyID'])) {
$actionParams
['UserSurveyID'] = $userLink['userSurveyID'];
}
$jsonParamString
= json_encode($actionParams);

$this
->execute("
INSERT INTO `token_links` (`linkID`, `token`, `actionPlugin`, `actionParams`) VALUES

({$userLink['userLinkID']}, '{$userLink['token']}', '$actionPlugin', '$jsonParamString');

"
);
}


$this
->dropTable('user_links');
}

/**
* Migrate Down.

*/

public function down()
{
$this
->execute("
DROP TABLE IF EXISTS `user_links`;

CREATE TABLE IF NOT EXISTS `user_links` (

`userLinkID` INT(11) unsigned NOT NULL AUTO_INCREMENT,

`token` VARCHAR(100) NOT NULL,

`userID` INT(11) unsigned NOT NULL,

`userSurveyID` INT(11) unsigned DEFAULT NULL,

`action` VARCHAR(16) NOT NULL,

PRIMARY KEY (`userLinkID`),

UNIQUE KEY `token` (`token`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

"
);

// userLinks to tokenLinks
$tokenLinks
= $this->fetchAll('SELECT * FROM token_links');
foreach ($tokenLinks as $tokenLink) {
$actionParams
= json_decode($tokenLink['actionParams'], true);
$action
= strtolower($tokenLink['actionPlugin']);
$userSurveyID
= isset($actionParams['UserSurveyID']) ?
$actionParams
['UserSurveyID'] : 'NULL';

$this
->execute("
INSERT INTO `user_links` (`userLinkID`, `token`, `userID`, `userSurveyID`, `action`) VALUES

({$tokenLink['linkID']}, '{$tokenLink['token']}', {$actionParams['UserID']}, $userSurveyID, '$action');

"
);
}


$this
->dropTable('token_links');
}
}