migrations icon indicating copy to clipboard operation
migrations copied to clipboard

`CREATE SCHEMA public` is added to all down migrations in Postgres

Open speller opened this issue 11 months ago • 4 comments

Bug Report

Q A
Version 3.8.3

Summary

I'm using the bundle with Postrgres 16. The database URL is postgresql://$DB_USER:$DB_PASSWORD@db:5432/$DB_NAME?serverVersion=16.2&charset=utf8. But on every doctrine:migrations:diff it creates migrations like the following:

final class Version20240311103945 extends AbstractMigration
{
    public function getDescription(): string
    {
        return '';
    }

    public function up(Schema $schema): void
    {
        // this up() migration is auto-generated, please modify it to your needs

    }

    public function down(Schema $schema): void
    {
        // this down() migration is auto-generated, please modify it to your needs
        $this->addSql('CREATE SCHEMA public');
    }
}

No matter what are other changes, it ALWAYS adds the $this->addSql('CREATE SCHEMA public'); line to all migrations.

How to fix it?

speller avatar Mar 11 '24 13:03 speller

We got the exact same problem. Dont know how to work around it :/

maluramichael avatar Mar 14 '24 08:03 maluramichael

Related to https://github.com/doctrine/dbal/issues/5609 and https://github.com/doctrine/dbal/issues/1110 I think.

greg0ire avatar Mar 21 '24 14:03 greg0ire

I'm having this problem, too. I've been manually removing the line because it causes errors when attempting to roll back to a previous migration.

ramsey avatar May 29 '24 18:05 ramsey

Reading related doctrine/dbal issues it seems that is no easy way to fix it on a lower lib level. Fix on one side causes some issues on the other, ex. filtering out 'public' scheme on PostgreSQLSchemaManager::listSchemaNames() make d:m:diff work well but brakes d:m:create (?). So in my case I decided to do a workaround by decorating one of the DiffGenerator dependency to just skip 'public' scheme during comparison. Using symfony it can be easily done by service configurator pattern.

# services.yaml
services:
    Doctrine\Migrations\Configuration\Migration\ConfigurationLoader: '@doctrine.migrations.configuration_loader'
    doctrine.migrations.dependency_factory:
        class: Doctrine\Migrations\DependencyFactory
        configurator: '@App\Migrations\DependencyFactoryConfigurator'
<?php

namespace App\Migrations;

use Doctrine\DBAL\Platforms\PostgreSQLPlatform;
use Doctrine\DBAL\Schema\Comparator;
use Doctrine\DBAL\Schema\PostgreSQLSchemaManager;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\DependencyFactory;
use Doctrine\Migrations\Generator\DiffGenerator;
use Doctrine\Migrations\Provider\EmptySchemaProvider;

class DependencyFactoryConfigurator
{
    public function __invoke(DependencyFactory $dependencyFactory)
    {
        $dependencyFactory->setDefinition(
            DiffGenerator::class,
            function () use ($dependencyFactory): DiffGenerator {
                $connection = $dependencyFactory->getConnection();
                $schemaManager = $connection->createSchemaManager();
                $platform = $connection->getDatabasePlatform();
                if ($platform instanceof PostgreSQLPlatform) {
                    $schemaManager = new class($connection, $platform) extends PostgreSQLSchemaManager {
                        public function createComparator(): Comparator
                        {
                            return new class($this->_platform) extends Comparator {
                                public function compareSchemas(Schema $fromSchema, Schema $toSchema)
                                {
                                    $schemaDiff = parent::compareSchemas($fromSchema, $toSchema);
                                    if (isset($schemaDiff->newNamespaces['public'])) {
                                        unset($schemaDiff->newNamespaces['public']);
                                    }
                                    return $schemaDiff;
                                }
                            };
                        }
                    };
                }
                return new DiffGenerator(
                    $connection->getConfiguration(),
                    $schemaManager,
                    $dependencyFactory->getSchemaProvider(),
                    $platform,
                    $dependencyFactory->getMigrationGenerator(),
                    $dependencyFactory->getMigrationSqlGenerator(),
                    new EmptySchemaProvider($schemaManager)
                );
            }
        );
    }
}

PawelSuwinski avatar Sep 24 '24 13:09 PawelSuwinski