7
dynamic:
driver:   %database_driver%
host:     %database_host%
port:     %database_port%
dbname:   %database name%
user:     %database_user%
password: %database_password%
charset:  UTF8

Hi everybody

I would like to connect to multiple databases dynamically. I read this tutorial http://symfony.com/doc/current/cookbook/doctrine/multiple_entity_managers.html and it works as it was explained.

But my only problem is to change the value of dbname directly from my Controller to connect to all my databases.

It will be 24 hours that I am on this problem. if you have ideas I really need it

6
  • Just to be sure, you have separate database servers, right? Not just different schema on the same server? Commented Nov 15, 2017 at 19:05
  • I have a master database that lists the databases of the companies, the companies one has the choice to use a model A or a model B, the databases are saved locally Commented Nov 15, 2017 at 19:08
  • The same as @Don'tPanic and if you could post the full database .configuration Commented Nov 15, 2017 at 19:09
  • I have not implemented it yet, that's why I'm asking for help Commented Nov 15, 2017 at 19:11
  • Are the databases variables or always the same in master database? Commented Nov 15, 2017 at 19:23

2 Answers 2

11

Your code example shows only one connection. You've to define to database connection, like the example from the documentation:

Easy hack: don't use an entity manager, but just connection.

If you want an easy way out, don't use an EntityManager at all. It might be overkill if you only want to get some information about the database and don't want to store information or use Entities. Then, just create a custom connection and use 'vanilla' SQL:

$this->get('doctrine.dbal.connection_factory')->createConnection($params);

Your question does not say how many database you expect. So let's describe two possibilities: a small number of (fixed) database or a dynamic connection.

Multiple connections, the simple way

doctrine:
    dbal:
        default_connection: default
        connections:
            default:
                driver:   pdo_mysql
                host:     '%database_host%'
                port:     '%database_port%'
                dbname:   '%database_name%'
                user:     '%database_user%'
                password: '%database_password%'
                charset:  UTF8
            model_a:
                driver:   pdo_mysql
                host:     '%database_hosta%'
                port:     '%database_porta%'
                dbname:   '%database_namea%'
                user:     '%database_usera%'
                password: '%database_passworda%'
                charset:  UTF8
            model_b:
                driver:   pdo_mysql
                host:     '%database_hostb%'
                port:     '%database_portb%'
                dbname:   '%database_nameb%'
                user:     '%database_userb%'
                password: '%database_passwordb%'
                charset:  UTF8
    orm:
        default_entity_manager: default
        entity_managers:
            default:
                connection: default
            model_a:
                connection: model_a
            model_b:
                connection: model_b

By default, connection default will be used. In your controller, you can switch to another connection:

$customerEm = $this->getDoctrine()->getManager('model_a');

And of course, you can dynamically choose your Manager:

//just an example, I don't know how you choose which database to use.
$managerName = $company->getModelName();
$em = $this->getDoctrine()->getManager($managerName);

Dynamically create EntityManager

The DoctrineBundle has no support for dynamic values (other than configured values like the first example). You can create your own EntityManager, if you don't want (or can't) define multiple connections because the dynamic table name.

Create a factory and define it a service:

class EntityManagerFactory
{
    public function createManager($dbname)
    {
        $isDevMode = false;
        $config = Setup::createAnnotationMetadataConfiguration(array(__DIR__."/src"), $isDevMode);
        // or if you prefer yaml or XML
        //$config = Setup::createXMLMetadataConfiguration(array(__DIR__."/config/xml"), $isDevMode);
        //$config = Setup::createYAMLMetadataConfiguration(array(__DIR__."/config/yaml"), $isDevMode);

        $conn = [
            'driver' => 'pdo_mysql',
            'username' => 'foo',
            'password' => 'foo',
            'dbname' => $dbname
        ];

        // obtaining the entity manager
        return EntityManager::create($conn, $config);
    }
}

And use it in your controller:

public function controllerAction()
{
    $em = $this->get(EntityManagerFactory::class)->getManager('model-name');
}
Sign up to request clarification or add additional context in comments.

5 Comments

Stephane thank you, so I use the second solution, if I want to use the entities provided for model b, with the manager I just created, it is possible?
I'm not sure I understand your question. What do you mean by second solution? Dynamically create EntityManager?
yes, i use Dynamically create EntityManager.I would like to use the entities
Please give some background information about your system. What do you mean by 'the entities'? Do you have 1 model with multiple databases (table structure identical, only data differs)? Or two models (A and B) and my database that are based on A or B?
Just for the sake of completness. Shouldn't the second part of the second solutions be something like: "$em = $this->get(EntityManagerFactory::class)->createManager('model-name');" ?
0
/*
$connectionParams = array(
    'dbname' => 'mydb',
    'user' => 'user',
    'password' => 'secret',
    'host' => 'localhost',
    'driver' => 'pdo_mysql',
    );
*/
             
$connectionParams = array(
    'url' => 'mysql://user:secret@localhost/mydb',
    );
            
$conn = \Doctrine\DBAL\DriverManager::getConnection($connectionParams);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.