是否可以在 Symfony 中为同一个包使用两个不同的文档管理器和不同的数据库?

Is it possible to use two diffrent document managers with different databases for the same bundle in Symfony?

我的目标是让两个不同的文档管理器连接到共享相同数据库模型的不同数据库。

我已经对我的数据库模型进行了大量更改,我想编写一个自定义迁移脚本,从旧模型中检索对象并读取其值,然后使用旧对象的信息在新模式上创建一个新对象。

我在这里找到了一个相关的 Whosebug 问题: Working with two entity managers in the same bundle in Symfony2

但是,此解决方案建议为每个数据库使用不同的前缀,并将数据模型的 类 存储在不同的文件夹中:

doctrine:
dbal:
    default_connection:   default
    connections:
        default:
            driver:   %database_driver%
            host:     %database_host%
            port:     %database_port%
            dbname:   %database_name%
            user:     %database_user%
            password: %database_password%
            charset:  UTF8
        second:
            driver:   %database_sqlite_driver%
            host:     ~
            port:     ~
            dbname:   %database_sqlite_shop_name%
            path:     %database_sqlite_shop_name%
            user:     ~
            password: ~
            charset:  UTF8

orm:
    auto_generate_proxy_classes: %kernel.debug%
    default_entity_manager:   default
    entity_managers:
        default:
            connection:       default
            mappings:
                YourBundle:
                  # you must specify the type
                  type:     "annotation"    
                  # The directory for entity (relative to bundle path)
                  dir:      "Entity/FirstDb"        
                  #the prefix 
                  prefix:   "Your\Bundle\Entity\FirstDb" 
        shop:
            connection:       second
            mappings:
                YourBundle:
                  type: "annotation"
                  #here the second path where entity for the connection stand
                  dir: "Entity/SecondDb" 
                  #the prefix
                  prefix: "Your\Bundle\Entity\SecondDb" 

我真的很想拥有两个不同的文档管理器对象,它们在同一文件夹中共享相同的模型,但连接到不同的数据库。这可能吗?

我发现在同一个 Symfony Bundle 中确实可以连接到不同的数据库。这个答案使我想到了一个可能的解决方案:

#services.yml
acme_app.dynamic_connection:
class: %acme.dynamic_doctrine_connection.class%
calls:
    - [setDoctrineConnection, @doctrine.dbal.default_connection]]


<?php

namespace Acme\Bundle\AppBundle;

use Doctrine\DBAL\Connection;
use Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException;
use Exception;

class DynamicDoctrineConnection
{
    /**
     * @var Connection
     */
    private $connection;

    /**
     * Sets the DB Name prefix to use when selecting the database to connect to
     *
     * @param  Connection       $connection
     * @return SiteDbConnection $this
     */
    public function setDoctrineConnection(Connection $connection)
    {
        $this->connection = $connection;

        return $this;
    }

    public function setUpAppConnection()
    {
        if ($this->request->attributes->has('appId')) {
            $connection = $this->connection;
            $params     = $this->connection->getParams();

            // we also check if the current connection needs to be closed based on various things
            // have left that part in for information here
            // $appId changed from that in the connection?
            // if ($connection->isConnected()) {
            //     $connection->close();
            // }

            // Set default DB connection using appId
            //$params['host']   = $someHost;
            $params['dbname'] = 'Acme_App'.$this->request->attributes->get('appId');

            // Set up the parameters for the parent
            $connection->__construct(
                $params, $connection->getDriver(), $connection->getConfiguration(),
                $connection->getEventManager()
            );

            try {
                $connection->connect();
            } catch (Exception $e) {
                // log and handle exception
            }
        }

        return $this;
    }
}

使用上述解决方案,可以编写一个服务,调用该服务可以将当前实体管理器连接到的数据库更改为不同的数据库。

不幸的是,上面的 解决方案仅适用于 PDO 驱动程序 (Mysql)。 由于我们的技术栈包括 mongodb 并且我们使用 doctrine-mongodb bundle 我不得不寻找一个 不同的解决方案 .

doctrine-mongodb 文档有一个关于在此处设置自定义文档管理器的部分: http://docs.doctrine-project.org/projects/doctrine-mongodb-odm/en/latest/reference/introduction.html

我无法获得正确的 doctrine-mongodb odm 文档映射以使用文档中的说明,因此对我来说唯一的解决方案是创建一个简单的 PHP mongoclient 连接:

$mongo = new \Mongo('mongodb://localhost:27017');
$legacyDbDocumentMangager = $mongo->selectDB('backed_up_prod_db');
$legacyUserCollection = $legacyDbDocumentMangager->selectCollection('User');
$user = $legacyUserCollection->findOne(array('email' => 'matyas@whosebug.com'));

这个简单的 php mongodb 驱动程序和 doctrine-mongodb odm 之间的唯一区别是这个驱动程序的查询结果是关联数组,而doctrine-mongodb odm 潜水员是对象。

我希望此信息对某人有用。