I have two databases one for production and one for backup purposes. I want to have a service in Symfony, called from a command, that can execute some SQL queries in one of these two databases depending on the name of the connecction passed by the command. The problem is that I don't know how to obtain the DBAL connection using the name of the connection as a parameter.
I use Symfony 3.4.
The config.yml is:
#config.yml
doctrine:
dbal:
default_connection: prod
connections:
prod:
driver: '%database_driver1%'
host: '%database_host1%'
port: '%database_port1%'
dbname: '%database_name1%'
user: '%database_user1%'
password: '%database_password1%'
charset: UTF8
backup:
driver: '%database_driver2%'
host: '%database_host2%'
port: '%database_port2%'
dbname: '%database_name2%'
user: '%database_user2%'
password: '%database_password2%'
charset: UTF8
Mi idea is having a service like this:
<?php
namespace ErqBundle\Services;
use Doctrine\DBAL\Driver\Connection;
class ProcSQL {
public function exSQL($conn_name)
{
// How to obtain the connection ????
$conn=$this->getDoctrine()->getConnection($conn_name);
// This doesn't work !!!
$sql = "SELECT ....";
$stmt = $conn->query($sql);
}
}
But I haven't been able to obtain the connection from a name of connection like "prod" or "backup" (something like: $conn=$this->getDoctrine()->getConnection($conn_name) )
The only way I have made it work is defining again the connection parameters and make the connection like this:
public function exSQL()
{
$config = new \Doctrine\DBAL\Configuration();
$connectionParams = array(
'dbname' => 'dbname',
'user' => 'user',
'password' => 'password',
'host' => 'prod_host',
'driver' => 'pdo_mysql',
);
$conn = \Doctrine\DBAL\DriverManager::getConnection($connectionParams, $config);
$sql = "SELECT ...";
$stmt = $conn->query($sql);
while ($row = $stmt->fetch()) {
var_dump($row);
}
// This works !!!
}
Thanks in advance.
You can use dependency injection like this:
use \Doctrine\ORM\EntityManager;
class ProcSQL {
private $entityManager
public function __construct(EntityManager $entityManager)
{
$this->entityManager = $entityManager;
}
public function exSQL($conn_name)
{
$conn = $this->entityManager->getConnection($conn_name);
}
}
You need to declare your service like this (I don't know if you are using autowiring or not):
ErqBundle\Services\ProcSql:
class: ErqBundle\Services\ProcSql
arguments:
- '@doctrine.orm.entity_manager'
Thanks to both of you. Thinking in your answers I've tried:
I added:
use \Doctrine\ORM\EntityManager;
and called the Doctrine EntityManager directly in the construct method.
public function __construct(EntityManager $entityManager)
{
$this->entityManager = $entityManager;
}
public function exSQL($conn_name)
{
$conn = $this->entityManager->getConnection($conn_name);
$sql = "SELECT ...";
$stmt = $conn->query($sql);
while ($row = $stmt->fetch()) {
var_dump($row);
}
}
and it works!!!!!
Thanks a lot!!!
If you have access to doctrine, you can do something like
$this->getDoctrine()->getManager('backup');
But as @AlessandroMinoccheri says, it's better to inject it/them directly.
If you need to inject the default one, just use doctrine.orm.entity_manager
, if you need to inject the backup
one, use doctrine.orm.backup_entity_manager
The best way in 2023 is to type hint the Connection correctly.
Autowiring multiple Connections
You can autowire different connections by type-hinting your service arguments with the following syntax: Doctrine\DBAL\Connection $Connection. For example, to inject a connection with the name purchase_logs use this:
public function __construct(Connection $connectionNameConnection)
{
$this->connection = $purchaseLogsConnection;
}
As for your case, this would result in:
private $prodConnection;
private $backupConnection;
public function __construct(Connection $prodConnection, Connection $backupConnection)
{
$this->prodConnection= $prodConnection;
$this->backupConnection= $backupConnection;
}
public function exSQL() {
$conn = $this->prodConnection;
// $conn = $this->backupConnection;
$sql = 'SELECT * FROM ...';
$stmt = $conn->prepare($sql);
$stmt->execute();
}
Documentation: Autowiring multiple Connections
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.