Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DBAL-1168: Schema's getMigrateFromSql always adds CREATE SCHEMA #1110

Open
doctrinebot opened this issue Mar 11, 2015 · 32 comments

Comments

Projects
None yet
@doctrinebot
Copy link

commented Mar 11, 2015

Jira issue originally created by user vbence:

I originally posted this to Migrations; noticing that all the generated down() methods start with a "CREATE SCHEMA public" line.

Inspecting the return from Schema#getMigrateFromSql it indeed contains the create statement.

@doctrinebot

This comment has been minimized.

Copy link
Author

commented May 19, 2015

Comment created by asentner:

I am also having this issue. The down() method always adds: $this->addSql('CREATE SCHEMA public');

Same environment, also using Postgres.

Any chance this is on anyone's radar for a release in the near future?

@doctrinebot

This comment has been minimized.

Copy link
Author

commented May 28, 2015

Comment created by acasademont:

Hit by this too. The problem seems to be that the "public" namespace is not added to the table names by default and hence the diff between what postgres says (a "public" schema is created by default in the DB) and what our schema says.

I tried to solve this with a workaround by prepending "public." to all table names. It works for the first migration but then in the next migration will try to delete all tables without the "public." and create them again. So that's not working!

The solution is assuming that there's always a default 'public' namespace in the Schema.php class.

@cleentfaar

This comment has been minimized.

Copy link

commented Feb 10, 2016

Any updates on this? Would be nice to get rid of this in our version files

@josensanchez

This comment has been minimized.

Copy link

commented Mar 15, 2016

As @doctrinebot commented, the problem seems to be here:

        $fromSchema = $conn->getSchemaManager()->createSchema();
        $toSchema = $this->getSchemaProvider()->createSchema();

the first line builds the schema querying the database

SELECT schema_name AS nspname
          FROM   information_schema.schemata
...

and the second one builds it from the ORM metadata in your application

@ORM\Table(name="table_1" ...

there is a "public" schema in $fromSchema but since there is no @ORM\Table(name="table_1", schema="public"...) also there is no "public" schema in $toSchema

trying the @doctrinebot workaround @ORM\Table(name="table_1", schema="public"...) it's also useless as he already commented because table_1 and public.table_1 are two different things to the dbal, witch is logic.
but it will try to perform the next code every time.

create table public.table_1 ...  -- table already exists exception
drop table table_1

the drop command is without the "public." and I assume that it's to add support to tables without namespaces...

I don't see an easy solution for this issue. Either finding a way to define table_1 as an alias for public.table_1 (maybe in postgresql if a database object doesn't have a namespace defined, then the 'public' namespace is attached to it) or removing support in postgresql for no namespace objects, forcing always to define schema="public"

for the moment if anybody is working with postgresql and doctrine I suggest to use only the public schema or not use it at all.

@idchlife

This comment has been minimized.

Copy link

commented Aug 12, 2016

Yep, waiting issue to be resolved

@garex

This comment has been minimized.

Copy link

commented Aug 26, 2016

Can't use diff commands as schema always differs by those CREATE SCHEMA public.

garex added a commit to ekapusta/doctrine-phinx-bridge-bundle that referenced this issue Aug 27, 2016

Local rude fix of doctrine/dbal#1110
* Need to revert this after fixes in dbal and orm upstreams
@Melkij

This comment has been minimized.

Copy link

commented Oct 24, 2016

My workaround without modify library and waiting patch.
Add class in any namespace in application:

<?php

namespace EngineBundle\Doctrine;

use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\Tools\Event\GenerateSchemaEventArgs;

class MigrationEventSubscriber implements EventSubscriber
{
    public function getSubscribedEvents()
    {
        return array(
            'postGenerateSchema',
        );
    }

    public function postGenerateSchema(GenerateSchemaEventArgs $Args)
    {
        $Schema = $Args->getSchema();

        if (! $Schema->hasNamespace('public')) {
            $Schema->createNamespace('public');
        }
    }
}

Register event subscriber. For symfony this can be done in config:

# app/config/services.yml
services:
    doctrineMigrationDiffListener:
        class: EngineBundle\Doctrine\MigrationEventSubscriber
        tags:
            - { name: doctrine.event_subscriber, connection: default }

Works for me, no more useless CREATE SCHEMA public in down migration.

@teohhanhui

This comment has been minimized.

Copy link

commented Oct 25, 2016

@Melkij What about other schemas? For example when using PostGIS.

@garex

This comment has been minimized.

Copy link

commented Oct 25, 2016

@teohhanhui see my PR #2490

There is $platform->getDefaultSchemaName() -- then it will be unversal. Currently 'public' is hardcoded value in this solution.

@Melkij

This comment has been minimized.

Copy link

commented Oct 25, 2016

@teohhanhui I test only public schema. This is just workaround for my project, not complete solution.
I think same hasNamespace + createNamespace needed for any schemas, which is not used in any Entity. And for schemas in search_path setting.

@takeit takeit referenced this issue Feb 20, 2017

Merged

Return route id in menus API instead of an object #258

3 of 3 tasks complete
@vudaltsov

This comment has been minimized.

Copy link

commented Mar 21, 2017

Created a bundle addressing this issue

@isaackearl

This comment has been minimized.

Copy link

commented Jul 1, 2017

If you are using the Laravel doctrine package, here is a workaround: laravel-doctrine/migrations#51

@alemosk

This comment has been minimized.

Copy link

commented Jul 13, 2017

If it very old and very hard bug, why not replace constant 'CREATE SCHEMA ' to 'CREATE SCHEMA IF NOT EXISTS ' ?

Not beauty, but will no exceptions.

@Ocramius

This comment has been minimized.

Copy link
Member

commented Jul 13, 2017

@vudaltsov

This comment has been minimized.

Copy link

commented Dec 16, 2017

I think, I found a cleaner solution. At least for PostgreSQL.
And it looks like it follows @deeky666's advice in #2490 (comment) since it uses AbstractSchemaManager::getSchemaSearchPaths() through PostgreSqlSchemaManager::determineExistingSchemaSearchPaths().

<?php

declare(strict_types=1);

namespace App\EventListener;

use Doctrine\Common\EventSubscriber;
use Doctrine\DBAL\Schema\PostgreSqlSchemaManager;
use Doctrine\ORM\Tools\Event\GenerateSchemaEventArgs;
use Doctrine\ORM\Tools\ToolEvents;

class FixDefaultSchemaListener implements EventSubscriber
{
    /**
     * {@inheritdoc}
     */
    public function getSubscribedEvents(): array
    {
        return [
            ToolEvents::postGenerateSchema,
        ];
    }

    public function postGenerateSchema(GenerateSchemaEventArgs $args): void
    {
        $schemaManager = $args->getEntityManager()
            ->getConnection()
            ->getSchemaManager();

        if (!$schemaManager instanceof PostgreSqlSchemaManager) {
            return;
        }

        foreach ($schemaManager->getExistingSchemaSearchPaths() as $namespace) {
            if (!$args->getSchema()->hasNamespace($namespace)) {
                $args->getSchema()->createNamespace($namespace);
            }
        }
    }
}
@yurtesen

This comment has been minimized.

Copy link

commented Dec 29, 2017

I have also faced with this problem.

@greg0ire

This comment has been minimized.

Copy link
Member

commented Jan 18, 2018

@vudaltsov I don't think this bug happens on anything but Postgres, does it? Maybe create a PR?

@antonmedv

This comment has been minimized.

Copy link

commented Mar 27, 2018

Any updates?

@Ocramius

This comment has been minimized.

Copy link
Member

commented Mar 27, 2018

@antonmedv can you provide a failing test case for the DBAL test suite?

@antonmedv

This comment has been minimized.

@igorjacauna

This comment has been minimized.

Copy link

commented May 3, 2018

Any updates? I stopped a migration of project to doctrine because of this. 😞

@morozov

This comment has been minimized.

Copy link
Member

commented May 3, 2018

@igorjacauna I do not recall any work on this issue during the last year, so most likely no updates. Please feel free to submit a failing test.

@garex

This comment has been minimized.

Copy link

commented May 3, 2018

@igorjacauna I suggest you to switch to hibernate ))

@PedroDiSanti

This comment has been minimized.

Copy link

commented Nov 8, 2018

Is this bug still occurring while using Symfony 4 + Postgres?
Thanks for any help!

@mneute

This comment has been minimized.

Copy link

commented Nov 8, 2018

@PedroDiSanti : Yes, this is still occuring

@PedroDiSanti

This comment has been minimized.

Copy link

commented Nov 8, 2018

@PedroDiSanti : Yes, this is still occuring

Thanks, mate.

@ayrad

This comment has been minimized.

Copy link

commented Dec 23, 2018

This is still occuring. Even when there are no migrations to generate, the following line is added:

$this->addSql('CREATE SCHEMA public');

Full generated migration content could be found here.

@vasilvestre

This comment has been minimized.

Copy link

commented Jan 14, 2019

Still occurring, got some fresh news?

@Ocramius

This comment has been minimized.

Copy link
Member

commented Jan 14, 2019

@vasilvestre pick up #2490 if you can work on it.

@pc-trent

This comment has been minimized.

Copy link

commented Jan 14, 2019

Anyone know how to implement #1110 (comment) into a symfony4 project? What yaml file does it go into, and where?

Any help would be awesome.

@vudaltsov

This comment has been minimized.

@pc-trent

This comment has been minimized.

Copy link

commented Jan 29, 2019

@vudaltsov - legend thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.