鉴于我有通往 Doctrine 迁移课程的途径。我如何在 Doctrine 2 中以编程方式执行迁移?
我假设应该有一个干净的方法来通过 API 执行迁移,因为它可以用早期版本的 Doctrine 完成,如下所述: http://docs.doctrine-project.org/projects/doctrine1/en/latest/en/manual/migrations.html
由于我没有看到任何答案,我将尝试提供我的解决方案,以在 doctrine 中以编程方式(使用代码)执行迁移。
use Doctrine\DBAL\DriverManager;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\Configuration\Configuration;
use Doctrine\Migrations\Configuration\Connection\ExistingConnection;
use Doctrine\Migrations\Configuration\Migration\ExistingConfiguration;
use Doctrine\Migrations\DependencyFactory;
use Doctrine\Migrations\Metadata\Storage\TableMetadataStorageConfiguration;
use Doctrine\Migrations\MigratorConfiguration;
use Doctrine\Migrations\Provider\SchemaProvider;
use Doctrine\Migrations\Version\Direction;
// connection
$dbParams = [
'dbname' => 'database-name',
'user' => 'database-username',
'password' => 'database-password',
'host' => 'hostname',
'port' => 'port',
'driver' => 'pdo_mysql',
];
try {
$connection = DriverManager::getConnection($dbParams);
} catch (\Doctrine\DBAL\Exception $e) {
echo 'Problem connecting to DB. '.$e->getMessage();
die();
}
// configuration - Be careful what namespace you use
$configuration = new Configuration($connection);
$configuration->addMigrationsDirectory('MyAppNamespace\Migrations', __DIR__ . '/../migrations');
// we want the execution of the migration to make changes to the table doctrine_migration_versions - so the system is aware that executed the migration
$storageConfiguration = new TableMetadataStorageConfiguration();
$storageConfiguration->setTableName('doctrine_migration_versions');
$configuration->setMetadataStorageConfiguration($storageConfiguration);
$dependencyFactory = DependencyFactory::fromConnection(
new ExistingConfiguration($configuration),
new ExistingConnection($connection))
);
$planCalculator = $dependencyFactory->getMigrationPlanCalculator();
// which migration to execute / I assume latest /
$latestMigrationVersion = $dependencyFactory->getVersionAliasResolver()->resolveVersionAlias('latest');
// check if we have at least one migration version to execute
if(!$latestMigrationVersion->equals(new Version(0))){
try {
// so we will execute only latest ONE migration, if you need more, just find a way to list them in the first parameter of method getPlanForVersions()
$planUp = $planCalculator->getPlanForVersions(
[$latestMigrationVersion],
Direction::UP
);
$dependencyFactory->getMetadataStorage()->ensureInitialized();
// do the migration
$dependencyFactory->getMigrator()->migrate($planUp, (new MigratorConfiguration())->setAllOrNothing(false));
}catch (Exception $e){
echo 'There were problems during db-migration.'."\n".$e->getMessage()."\n\n";
}
}
希望它能帮助其他开发人员快速启动他的原型。 我试着详细介绍代码,这样人们就不会浪费时间去弄清楚每一个依赖项。
如果您在 Symfony 框架中使用 Doctrine 并发现此问题正在寻找从命令外部运行迁移的方法,请记住您可以通过自动装配访问已配置的 DependencyFactory。为此,使用别名公开服务:
services:
Doctrine\Migrations\DependencyFactory:
alias: 'doctrine.migrations.dependency_factory'
和往常一样自动装配:
public function someControllerAction(DependencyFactory $df): Response {
完成
话虽如此,在正常操作期间,您应该按照最小权限原则,以没有管理权限的受限用户连接到数据库。如果这样做,从您的应用程序运行迁移将失败。如果你不这样做,请考虑这样做。
我发现上面的代码对于在我的健康检查端点响应中包含迁移信息很有用,不一定要运行迁移。
假设您正在使用 Symfony 的DoctrineMigrationsBundle
要迁移到最新的可用版本,请使用:
doctrine:migrations:migrate
命令。
这里有更多可用的命令。