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

发布于 2024-11-26 17:17:08 字数 202 浏览 1 评论 0原文

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

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

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

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

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

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.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

朦胧时间 2024-12-03 17:17:08

您可以在迁移任务中使用 --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 添加到所有迁移中,以便您可以放心地在两个数据库中进行迁移。

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.

﹏雨一样淡蓝的深情 2024-12-03 17:17:08

这个问题有点老了,但当我问同样的事情时,它首先出现了。我在 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

那么您就不会在 config.yml 中包含 doctrine_migrations 配置。相反,为每个命令创建一个配置文件:

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

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"
三生殊途 2024-12-03 17:17:08

多年来我一直在使用 @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

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
再浓的妆也掩不了殇 2024-12-03 17:17:08

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

您可以为第二个数据库并将迁移放入其中。

The similar problem and solution: Symfony2 - Change Migration Directory

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

旧话新听 2024-12-03 17:17:08

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

中设置 MySQL像平常一样创建 .env ,但为其设置一个 MIGRATIONS_PATH="migrations/mysql" 属性。

然后创建一个 .env.test 并设置:

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

在您的 config/packages/doctrine_migrations.yaml 中,您更改从 env 文件获取的默认路径:

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

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

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将在migrations/mysqlmigrations/sqlite中为MySQL生成迁移SQLite。

I know this is an old threat but it's one of the top Google searches in 2023, this is how I've done it to generate migrations for both MySQL and SQLite with Symfony 6.3 without custom entity managers:

Setup your MySQL in your .env like you would usually do, but set a MIGRATIONS_PATH="migrations/mysql" property to it.

Then create a .env.test and set:

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

In your config/packages/doctrine_migrations.yaml you change default path to get from the env files:

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

Also enable MakerBundle for test env in bundles.php:

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

Now you can generate migrations using:

# 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

Doing this, Symfony will generate migrations for MySQL in migrations/mysql and migrations/sqlite for SQLite.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文