我正在尝试为 symfony 4.2 项目设置第二个数据库。一切似乎都工作正常,直到我运行迁移,其中所有迁移都在给定连接上执行,而不仅仅是其创建的连接的迁移。
按照 symfony 自己的文档,我的doctrine.yaml 看起来像这样:
doctrine:
dbal:
default_connection: default
connections:
default:
driver: 'pdo_mysql'
server_version: '5.7'
charset: utf8mb4
default_table_options:
charset: utf8mb4
collate: utf8mb4_unicode_ci
url: '%env(DATABASE_URL)%'
logging:
driver: 'pdo_mysql'
server_version: '5.7'
charset: utf8mb4
default_table_options:
charset: utf8mb4
collate: utf8mb4_unicode_ci
url: '%env(DATABASE_URL_LOG)%'
orm:
auto_generate_proxy_classes: '%kernel.debug%'
default_entity_manager: default
entity_managers:
default:
connection: default
naming_strategy: doctrine.orm.naming_strategy.underscore
auto_mapping: true
mappings:
App:
is_bundle: false
type: annotation
dir: '%kernel.project_dir%/src/Entity'
prefix: 'App\Entity'
alias: App
logging:
connection: logging
naming_strategy: doctrine.orm.naming_strategy.underscore
auto_mapping: false
mappings:
Log:
is_bundle: false
type: annotation
dir: '%kernel.project_dir%/src/Log'
prefix: 'App\Log'
alias: Log
现在通过此配置,我可以使用 --em=log/default 参数运行迁移命令,如下所示:
php bin/console doctrine:migrations:diff --em=log
php bin/console doctrine:migrations:migrate --em=log
您会得到预期的结果:当我添加 --em=log 时,它只会为我在 src/Log 创建的新实体创建新的迁移。
这是新实体:
<?php
namespace App\Log;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity()
*/
class LogItem
{
/**
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
* @ORM\Column(type="integer")
*/
private $id;
}
但是,迁移是在默认的 src/Migrations 文件夹中创建的,因此:
1)当我运行
doctrine:migrations:migrate --em=default
(在默认数据库中创建表)时也会执行此迁移
2)当我运行时,整个默认模式会加载到日志数据库中
doctrine:migrations:migrate --em=log
所以我认为解决方案是将实体管理器之间的迁移文件拆分到不同的目录中。但我花了几个小时却找不到为 symfony4 执行此操作的方法。另外,由于 symfony 文档完全没有提到这一点,我觉得现在的设置方式可能有问题。
那么谁能告诉我我在这里做错了什么?或者我可以(如果是的话:如何)拆分迁移文件,以便它只执行为给定实体管理器创建的迁移?
doctrine/doctrine-migrations-bundle
不支持开箱即用的多个实体管理器的迁移。此问题有多种解决方法,包括:
--configuration
命令的 doctrine:migrations:migrate
选项传递它(仅当您不需要将服务/依赖项注入到迁移中时才可行)avaibooksports/doctrine-migrations-multiple-database-bundle
(或滚动您自己的捆绑包),它实现了对每个实体管理器单独配置的支持(您可以在其中为每个实体的迁移指定单独的目录,并根据需要通过工厂注入服务)。我认为您的样本中有错字。
在您的
doctrine.yaml
文件中,实体管理器的名称为“default”和“logging”。
但在命令行示例中,您使用实体管理器名称“log”。 当您将标志从
--em=log
更改为 --em=logging
时,它应该可以工作。