开发者

Migrating multiple databases using doctrine2 with Symfony2

I have 2 databases db1 and db2 in symfony2 + doctrine2 and both databases are different from each other in terms of tables and their fields.

I need to work on migration. Things work fine as long as there is one database.

But it does not works when there are more than one databases.

Also, is there any way where I can provide entity manager specific migration settings.

开发者_JS百科

Or is there any way through which I can provide connection or entity manager in the migration class.


You can provide an entityManager using --em=name option in the migration task. I also add this piece of code, to avoid executing of the migration on another db by mistake:

    $parameters = $this->connection->getParams();
    $this->skipIf(
        $parameters['dbname'] != "my_db_name"
        'This is the other DB\'s migration, pass a correct --em parameter'
    );

I haven't found any other way to check the EM, so I can't help you if your databases have same names.

Also note, that you should add the skipIf to all your migrations, so you can migrate without worry in both you databases.


This question is a little old, but it came up first when I was asking the same thing. I found my answer in the Doctrine migrations configuration docs. Let's say you have connections for two databases, each with their own entity managers (mapped here with XML, not annotations, and not auto mapped so the schema configs can live in the same config/doctrine path):

# config.yml
doctrine:
dbal:
    default_connection: default
    connections:
        default:
            driver: '%database_driver%'
            ...
        special:
            driver: '%special_database_driver%'
orm:
    entity_managers:
        default:
            auto_mapping: false
            mappings:
                base:
                    type: xml
                    dir: '%kernel.root_dir%/../src/MyBundle/Resources/config/doctrine/base'
                    prefix: MyBundle\Entity
                    alias: Base
                    is_bundle: false
        special:
            auto_mapping: false
            connection: special
            mappings:
                special:
                    type: xml
                    dir: '%kernel.root_dir%/../src/MyBundle/Resources/config/doctrine/special'
                    prefix: MyBundle\Special
                    alias: Special
                    is_bundle: false

Then you do not include the doctrine_migrations configurations in config.yml. Instead, create a configuration file for each one:

# src/MyBundle/Resources/config/migrations/base.yml
name: BaseMigrations
migrations_namespace: MyBundle\Migrations\Base
table_name: Migrations
migrations_directory: src/MyBundle/Migrations/Base

# src/MyBundle/Resources/config/migrations/special.yml
name: SpecialMigrations
migrations_namespace: MyBundle\Migrations\Special
table_name: Migrations
migrations_directory: src/MyBundle/Migrations/Special

Then, whenever you run any migration command, specify both the entity manager and configuration:

bin/console doctrine:migrations:status --env=dev --em=special --configuration=src/MyBundle/Resources/config/migrations/special.yml

It's a bit to remember if running by hand, so you might want to wrap them up in your own command to make life easy (e.g. something like bin/console my:migrations:status --env=dev --db=special). It's also not an issue if you have a deploy bash script, like:

#!/bin/bash
ENVIRONMENT="$1"

# Run migrations for a configuration
function runMigrations()
{
    local CONFIG="$1"
    local MANAGER="$2"
    local STATUS="$(bin/console doctrine:migrations:status --env=${ENVIRONMENT} --configuration=${CONFIG} --em=${MANAGER})"

    case "${STATUS}" in
        *"Already at latest version"*)
            # Do nothing
            ;;
        *)
            runNextMigration $CONFIG $MANAGER
            ;;
    esac
}

# Run the next migration for a configuration
function runNextMigration()
{
    local CONFIG="$1"
    local MANAGER="$2"
    bin/console doctrine:migrations:migrate next --env=$ENVIRONMENT --configuration=$CONFIG --em=$MANAGER

    runMigrations $CONFIG $MANAGER
}

runMigrations "src/MyBundle/Resources/config/migrations/base.yml" "default"
runMigrations "src/MyBundle/Resources/config/migrations/special.yml" "special"


I've been using @iisisrael's answer for years. But after upgrading to doctrine/migrations 3.x I had to change the format of the config files. This is what I have now:

# config/packages/migrations/base.yaml
em: default
transactional: false
migrations_paths:
    Hyra\Migrations\Base: src/Migrations/Base
table_storage:
    table_name: migration_versions
# config/packages/migrations/special.yaml
em: special
transactional: false
migrations_paths:
    App\Migrations\Special: src/Migrations/Special
table_storage:
    table_name: migration_versions

And then I have these in my Makefile so that I don't need to remember the magic incantations:

migrate: migrate-base migrate-special

migrate-base:
    php bin/console doctrine:migrations:migrate --configuration=config/packages/migrations/base.yaml --no-interaction --allow-no-migration

migrate-special:
    php bin/console doctrine:migrations:migrate --configuration=config/packages/migrations/special.yaml --no-interaction --allow-no-migration

diff-migrations-base: migrate
    php bin/console doctrine:migrations:diff --configuration=config/packages/migrations/base.yaml

diff-migrations-special: migrate
    php bin/console doctrine:migrations:diff --configuration=config/packages/migrations/special.yaml


The similar problem and solution: Symfony2 - Change Migration Directory

You can create another migration folder for second DB and put migrations inside.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜