在Symfony中,是否可以对同一个bundle使用两个具有不同数据库的不同文档管理器?


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

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

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

我在这里发现了一个相关的stackoverflow问题:在Symfony2

中使用同一个bundle中的两个实体管理器

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

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中连接到不同的数据库。这个答案让我想到了一个可能的解决方案:https://stackoverflow.com/a/15110867/2174832

#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,我们使用理论-mongodb包我不得不寻找一个不同的解决方案

doctrine-mongodb文档中有一节关于在这里设置自定义文档管理器:http://docs.doctrine-project.org/projects/doctrine-mongodb-odm/en/latest/reference/introduction.html

我无法获得正确的教条-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@stackoverflow.com'));

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

我希望这些信息对某人有用。