Doctrine DBALにはスキーマの差分を調べる機能があるようです。
<?php
use Doctrine\DBAL\DriverManager;
use Doctrine\DBAL\Schema\Schema;
require "vendor/autoload.php";
$db = DriverManager::getConnection(['driver' => 'pdo_pgsql', 'dbname' => 'test']);
$schema = new Schema();
$table = $schema->createTable('posts');
$table->addColumn('id', 'integer');
$table->addColumn('title', 'string');
$table->setPrimaryKey(['id']);
$scm = $db->getSchemaManager();
$queries = $schema->getMigrateFromSql($scm->createSchema(), $db->getDatabasePlatform());
foreach ($queries as $q) {
echo $q, "\n";
$db->executeUpdate($q);
}
$scm->createSchema()
で現在のDB上のSchemaを取得でき、$schma->getMigrateFromSql()
(あるいは$schma->getMigrateToSql()
)で差分のSQLの配列を取得できます。
これで、初回実行時は、
CREATE TABLE posts (id INT NOT NULL, title VARCHAR(255) NOT NULL, PRIMARY KEY(id))
が実行されますが、二回目以降な何も実行されません。また、$table
の定義を以下のように変更すれば、
$table->addColumn('title', 'string', ['notnull' => false]);
$table->addColumn('body', 'text');
以下のALTER文が実行されます。
ALTER TABLE posts ALTER title DROP NOT NULL
ALTER TABLE posts ADD body TEXT NOT NULL
多分symfonyのdoctrine:schema:updateも似たようなことしてるんじゃないかと思います。
データベースのスキーマの変更は様々なケースがあるので必ずしもうまくいくとは限りませんが、単純なプロジェクトであればこれで充分のように思えます。
あと、これDoctrineのソースを見てたらこういうことできそうだということに気付いたという話なんですが、実際このような使い方をしているという事例はみかけませんでした。