avaibooksports/doctrine-migrations-multiple-database-bundle
composer require avaibooksports/doctrine-migrations-multiple-database-bundle
config/bundles.php:
AvaiBookSports\Bundle\MigrationsMutlipleDatabase\DoctrineMigrationsMultipleDatabaseBundle::class => ['all' => true],
config/packages/doctrine_migrations_multiple_database.yaml:
doctrine_migrations_multiple_database:
entity_managers:
default:
migrations_paths:
'DoctrineMigrations\Main': '%kernel.project_dir%/migrations/Main'
geonames:
migrations_paths:
'DoctrineMigrations\Geonames': '%kernel.project_dir%/migrations/Geonames'
Run migrations for the geonames entity manager:
php bin/console doctrine:migrations:migrate --em=geonames
Organize Migrations by EM:
default EM in migrations/Main.geonames EM in migrations/Geonames.DoctrineMigrations\Main\Version20230101000000).Command Execution:
--em to execute across all configured EMs.
php bin/console doctrine:migrations:migrate
--em to isolate migrations.
php bin/console doctrine:migrations:diff --em=geonames
Generate Migrations: Generate migrations for a specific EM:
php bin/console doctrine:migrations:generate --em=geonames
Schema Dumping: Dump schema for a specific EM:
php bin/console doctrine:migrations:dump-schema --em=geonames
CI/CD Pipelines:
Use --em to parallelize migrations in CI (e.g., run default and geonames in separate jobs).
# Example GitHub Actions step
- name: Run Default EM Migrations
run: php bin/console doctrine:migrations:migrate --em=default
- name: Run Geonames EM Migrations
run: php bin/console doctrine:migrations:migrate --em=geonames
Environment-Specific Configs:
Override doctrine_migrations_multiple_database.yaml per environment (e.g., config/packages/dev/doctrine_migrations_multiple_database.yaml) to exclude certain EMs in testing.
Custom Templates:
Set custom_template in config to enforce migration file naming conventions:
doctrine_migrations_multiple_database:
entity_managers:
default:
custom_template: '%kernel.project_dir%/templates/migration.tpl.php'
Namespace Conflicts:
doctrine:migrations:diff without --em may fail if migrations share namespaces across EMs.--em when using --namespace:
php bin/console doctrine:migrations:diff --namespace=DoctrineMigrations\Geonames --em=geonames
Unsupported Configs:
connection and em in doctrine_migrations.yaml are ignored. Use entity_managers in doctrine_migrations_multiple_database.yaml instead.Metadata Storage:
doctrine_migration_versions_default, doctrine_migration_versions_geonames).table_name is unique per EM or use a naming convention like {em}_migration_versions.Command Limitations:
doctrine:migrations:version) may not support --em in older versions.Symfony 6+ Deprecations:
0.4.0).composer require avaibooksports/doctrine-migrations-multiple-database-bundle:^0.4
Dry Runs:
Use --dry-run to preview changes before executing:
php bin/console doctrine:migrations:migrate --em=geonames --dry-run
Verbose Output:
Add -v or -vv for detailed logs:
php bin/console doctrine:migrations:status --em=default -vv
Check EM Configuration:
Verify EM names and paths in doctrine_migrations_multiple_database.yaml match your config/packages/doctrine.yaml:
# Example from doctrine.yaml
doctrine:
dbal:
connections:
default: { ... }
geonames: { ... }
orm:
entity_managers:
default: { ... }
geonames: { ... }
Custom Migration Factories:
Override Doctrine\Migrations\Version\MigrationFactory in config to enforce custom logic:
doctrine_migrations_multiple_database:
entity_managers:
default:
services:
'Doctrine\Migrations\Version\MigrationFactory': 'App\CustomMigrationFactory'
Post-Migration Hooks: Use Symfony’s event system to trigger actions after migrations:
// src/EventListener/MigrationListener.php
namespace App\EventListener;
use Doctrine\Migrations\Event\PostMigrationEventArgs;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class MigrationListener implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return [
'doctrine.migrations.post_migration' => 'onPostMigration',
];
}
public function onPostMigration(PostMigrationEventArgs $args)
{
// Custom logic (e.g., cache invalidation, notifications)
}
}
Dynamic EM Configuration: Load EM configs dynamically (e.g., from a database) by extending the bundle or using a compiler pass:
// src/DependencyInjection/Compiler/MigrationsCompilerPass.php
namespace App\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
class MigrationsCompilerPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
if (!$container->has('doctrine_migrations_multiple_database.entity_managers')) {
return;
}
// Dynamically add EMs from a service
}
}
Testing: Mock migrations in PHPUnit by overriding the migration service:
// tests/Functional/MigrationsTest.php
use Doctrine\Migrations\Configuration\Connection\ConnectionConfiguration;
use Doctrine\Migrations\Configuration\Migration\PhpFile;
$container->get('doctrine_migrations_multiple_database.entity_managers')->add(
'test_em',
new ConnectionConfiguration([], [], new PhpFile('tests/Migrations'))
);
How can I help you explore Laravel packages today?