We will see how to manage an admin interface that connects
to multiple servers.
In our example, we have set up a default
MySQL server that manages our admin interface. Users, media,
etc.
And we have set up a PostgreSQL server that contains a
table we wish to manage.
We can add as many servers as we wish.
Our MySQL Server
We have traditionally set up a Symfony Sonata instance by default with a classic MySQL connection. So we can create our database, the schema, and the default user of our admin interface.
php bin/console doctrine:database:create
php bin/console doctrine:schema:update --force
php bin/console fos:user:create --super-admin

Our PostgreSQL Server
On the other hand, we have a PostgreSQL server containing a "test" table.

The Connections
In recent versions of Symfony, the credentials for connections are
managed in the .env file at the root of your project.
We will
create 1 connection for each server.
DATABASE_URL_PGSQL=pgsql://tbourdin:123456@127.0.0.1:5432/test?
DATABASE_URL_MYSQL=mysql://root:toor@127.0.0.1:3306/symfony-sonata-skeleton?serverVersion=5.7
Then we will configure our Doctrine settings by creating a default
connection (MySQL) and an additional connection for our PostgreSQL
server.
Be careful, to avoid confusion, we use an underscore
naming "_" instead of dashes "–" because Symfony will then convert
our "–" to "_" and the mapping will not be done
correctly.
We specify that all our default entities will be
managed in src/entity/ServerMysql and that the entities that need
to connect to Pgsql will all be stored in the directory
/src/Entity/ServerPgsql
doctrine:
dbal:
default_connection: db_mysql_local
types:
json: Sonata\Doctrine\Types\JsonType
connections:
db_mysql_local:
url: '%env(resolve:DATABASE_URL_MYSQL)%'
driver: 'pdo_mysql'
server_version: '5.7'
charset: utf8
default_table_options:
charset: utf8mb4
collate: utf8mb4_unicode_ci
db_pgsql_local:
url: '%env(resolve:DATABASE_URL_PGSQL)%'
driver: 'pdo_pgsql'
server_version: '9.6.11'
charset: utf8
default_table_options:
charset: utf8mb4
collate: utf8mb4_unicode_ci
# IMPORTANT: You MUST configure your server version,
# either here or in the DATABASE_URL env var (see .env file)
#server_version: '5.7'
orm:
auto_generate_proxy_classes: true
default_entity_manager: App
entity_managers:
#default code, the sonata admin, that use the default connexion (no need to define it here)
App:
connection: db_mysql_local
naming_strategy: doctrine.orm.naming_strategy.underscore
auto_mapping: true
mappings:
ApplicationSonataMediaBundle: ~
SonataMediaBundle: ~
App:
is_bundle: false
type: annotation
dir: '%kernel.project_dir%/src/Entity/ServerMysql'
prefix: 'App\Entity\ServerMysql'
alias: App
#our pgSql entities that use our pgsql connexion
app-pgsql:
connection: db_pgsql_local
naming_strategy: doctrine.orm.naming_strategy.underscore
auto_mapping: false
mappings:
AppPgsql:
is_bundle: false
type: annotation
dir: '%kernel.project_dir%/src/Entity/ServerPgsql'
prefix: 'App\Entity\ServerPgsql\'
alias: AppPgsql
And to verify our procedure we try to manage our test interface

And of course, it does not work. Because our entity is stored in
our default directory.
So we move it to our directory
"/src/Entity/ServerPgsql"
We just need to modify the service
and the entity definition, and we're good!
#/config/services.yaml
admin.table1:
class: App\Admin\Table1Admin
arguments: [~, App\Entity\ServerPgsql\Table1, App\Controller\Table1AdminController]
tags:
- { name: sonata.admin, manager_type: orm, group: admin, label: Table1 }
public: true
<?php
namespace App\Entity\ServerPgsql;
use Doctrine\ORM\Mapping as ORM;
/**
* Table1
*
* @ORM\Table(name="table1")
* @ORM\Entity
*/
class Table1
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="SEQUENCE")
* @ORM\SequenceGenerator(sequenceName="table1_id_seq", allocationSize=1, initialValue=1)
*/
private $id;
/**
* @var string|null
*
* @ORM\Column(name="var1", type="string", length=250, nullable=true)
*/
private $var1;
/**
* @var json|null
*
* @ORM\Column(name="var2", type="json", nullable=true)
*/
private $var2;
public function getId(): ?int
{
return $this->id;
}
public function getVar1(): ?string
{
return $this->var1;
}
public function setVar1(?string $var1): self
{
$this->var1 = $var1;
return $this;
}
public function getVar2(): ?array
{
return $this->var2;
}
public function setVar2(?array $var2): self
{
$this->var2 = $var2;
return $this;
}
}
