使用 doctrine2 和 Symfony2 迁移多个数据库

问题描述 投票:0回答:5

我在 symfony2 + doctrine2 中有 2 个数据库 db1 和 db2,这两个数据库在表及其字段方面彼此不同。

我需要从事移民工作。只要有一个数据库,事情就可以正常进行。

但是当有多个数据库时,它不起作用。

此外,有什么方法可以提供实体管理器特定的迁移设置。

或者有什么方法可以在迁移类中提供连接或实体管理器。

migration doctrine-orm multiple-databases
5个回答
16
投票

您可以在迁移任务中使用 --em=name 选项提供一个 entityManager。我还添加了这段代码,以避免错误地在另一个数据库上执行迁移:

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

我还没有找到任何其他方法来检查 EM,所以如果你的数据库同名我帮不了你。

另请注意,您应该将 skipIf 添加到所有迁移中,这样您就可以放心地在两个数据库中迁移。


10
投票

这个问题有点老了,但是在我问同样的事情的时候第一个出现了。我在Doctrine 迁移配置文档 中找到了我的答案。假设您有两个数据库的连接,每个数据库都有自己的实体管理器(此处使用 XML 映射,而不是注释,并且没有自动映射,因此模式配置可以存在于相同的

config/doctrine
路径中):

# 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

然后你

doctrine_migrations
中包含
config.yml
配置。相反,为每个创建一个配置文件:

# 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

然后,无论何时运行任何迁移命令,都指定实体管理器和配置:

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

如果手动运行有点需要记住,因此您可能希望将它们包装在自己的命令中以使生活更轻松(例如

bin/console my:migrations:status --env=dev --db=special
)。如果您有部署 bash 脚本,这也不是问题,例如:

#!/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"

1
投票

多年来我一直在使用@iisisrael 的答案。但是升级到

doctrine/migrations 3.x
后,我不得不更改配置文件的格式。这就是我现在拥有的:

# 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

然后我将这些放在我的 Makefile 中,这样我就不需要记住魔法咒语了:

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

0
投票

类似问题及解决方案:Symfony2 - Change Migration Directory

您可以为第二个数据库创建另一个迁移文件夹并将迁移放入其中。


0
投票

我知道这是一个古老的威胁,但它是 2023 年谷歌最热门的搜索之一,这就是我在没有自定义实体管理器的情况下使用 Symfony 6.3 为 MySQL 和 SQLite 生成迁移的方法:

像往常一样在

.env
中设置 MySQL,但要为其设置一个
MIGRATIONS_FOLDER="migrations/mysql"
属性。

然后创建一个

.env.test
并设置:

APP_ENV=test
DATABASE_URL="sqlite:///%kernel.project_dir%/var/data.db"
MIGRATIONS_FOLDER="migrations/sqlite"

在您的

config/packages/doctrine_migrations.yaml
中,您更改默认目录以从环境文件中获取:

doctrine_migrations:
    migrations_paths:
        'DoctrineMigrations': '%kernel.project_dir%/%env(string:MIGRATIONS_FOLDER)%'
    enable_profiler: false

同时在 bundles.php 中为测试环境启用 MakerBundle:

Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true, 'test' => true],

现在您可以使用以下方法生成迁移:

# for MySQL
php bin/console make:migration
php bin/console doctrine:migration:migrate

# for SQLite
php bin/console make:migration --env=test
php bin/console doctrine:migration:migrate --env=test

这样做,Symfony 将在

src/migrations/mysql
中为 MySQL 生成迁移,为 SQLite 生成
src/migrations/sqlite
中的迁移。

© www.soinside.com 2019 - 2024. All rights reserved.