7

I am using Doctrine ORM 2.6.1 in a Symfony 3.4.4 project. Some of my instances work on a MySQL database, some on Postgresql, and a few installations even access a MicosoftSQL server. This works fine without any special changes to my project or entities, I only have to configure the corresponding connection parameters.

But: if I create migrations, only statements compatible with the current database connection are created in the migration file.

I develop with a postgres-conncection, so I only produce postgresql-statements, like:

class Version20180430083616 extends AbstractMigration
{
    public function up(Schema $schema)
    {
        // this up() migration is auto-generated, please modify it to your needs
        $this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.');

        $this->addSql('DELETE FROM document_category');
        $this->addSql('DROP SEQUENCE document_category_id_seq CASCADE');
        $this->addSql('DROP TABLE document_category');
    }

    public function down(Schema $schema)
    {
        // this down() migration is auto-generated, please modify it to your needs
        $this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.');
        //...
    }
}

My Question: How can I tell the migrations bundle to create statements for each platform, like:

class Version20180430083616 extends AbstractMigration
{
    public function up(Schema $schema)
    {
        // this up() migration is auto-generated, please modify it to your needs
        if($this->connection->getDatabasePlatform()->getName() == 'postgresql'){

            $this->addSql('DELETE FROM document');
            $this->addSql('DELETE FROM document_category');
            $this->addSql('DROP SEQUENCE document_category_id_seq CASCADE');
            $this->addSql('DROP TABLE document_category');
        } else if($this->connection->getDatabasePlatform()->getName() == 'mysql'){
            ...
        } else if ($this->connection->getDatabasePlatform()->getName() == 'mssql') { // MicrosoftSQL ?
            ...
        }
    }
}

Edit:

So, I think the only solution to my problem is to define multiple database connections and entity managers, and to always create a distinct migration for each connection type. According to this article, I can define several connections as:

2
  • No can do, sorry. Doctrine's migration tool doesn't work this way. Commented Jun 21, 2018 at 13:35
  • Thanks for your answer. I think I would have to define several concurrent database connections in my dev environment and then create migrations for each. Is there a way to perform entity writes to multiple databases automatically? Commented Jun 22, 2018 at 8:35

2 Answers 2

6

I found a doable solution:

inf config.yml I define one connection and one EntityManager per database type:

doctrine:
    dbal:
        default_connection: pgdb
        connections:
            pgdb:
                driver: pdo_pgsql
                host: db
                port: 5432
                name: pgdb
                user: postgres
                password: example
                charset: utf8
                mapping_types:
                    enum: string
            mysql:
                driver: pdo_mysql
                host: mysqlhost
                port: 3306
                name: mydb
                dbname: mydb
                user: root
                password: xxx
                charset: utf8mb4
                default_table_options:
                    collate: utf8mb4_unicode_ci
                mapping_types:
                    enum: string
            mssql:
                driver: pdo_sqlsrv
                host: mssqlhost
                port: 1433
                name: msdb
                dbname: testdb
                user: sa
                password: xxx
                charset: utf8
                mapping_types:
                    enum: string

    orm:
        auto_generate_proxy_classes:  false
        proxy_dir:            '%kernel.cache_dir%/doctrine/orm/Proxies'
        proxy_namespace:      Proxies
        entity_managers:
            default:
                connection: pgdb
                naming_strategy: doctrine.orm.naming_strategy.underscore
                mappings:
                    AppBundle: ~ 
            my:
                connection: mydb
                naming_strategy: doctrine.orm.naming_strategy.underscore
                mappings:
                    AppBundle: ~
            ms:
                connection: msdb
                naming_strategy: doctrine.orm.naming_strategy.underscore
                mappings:
                    AppBundle: ~

Then, I can issue the diff-command 3 times instead of only once

$ bin/console doctrine:migrations:diff --em=default
$ bin/console doctrine:migrations:diff --em=my
$ bin/console doctrine:migrations:diff --em=ms

This creates three migrations each starting with a fence line:

$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'mssql', 'Migration can only be executed safely on \'mssql\'.');

in which I exchange abortIf by skipIf, such that the migration process is not aborted if the current migration if for a different database type, but just skipped:

$this->skipIf($this->connection->getDatabasePlatform()->getName() !== 'mssql', 'Migration can only be executed safely on \'mssql\'.');

I hope this helps somebody.

Sign up to request clarification or add additional context in comments.

Comments

0

For someone who'll search how to replace deprecated on DBAL 3

$this->connection->getDatabasePlatform()->getName() == 'mysql'

Here is the solution:

use Doctrine\DBAL\Platforms\MySQLPlatform;
...
$this->connection->getDatabasePlatform() instanceof MySQLPlatform

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.