Skip to content

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

Closed
@doctrinebot

Description

@doctrinebot

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.

Activity

doctrinebot

doctrinebot commented on May 19, 2015

@doctrinebot
Author

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

doctrinebot commented on May 28, 2015

@doctrinebot
Author

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

cleentfaar commented on Feb 10, 2016

@cleentfaar

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

josensanchez

josensanchez commented on Mar 15, 2016

@josensanchez

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

idchlife commented on Aug 12, 2016

@idchlife

Yep, waiting issue to be resolved

garex

garex commented on Aug 26, 2016

@garex

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

added a commit that references this issue on Aug 27, 2016
Melkij

Melkij commented on Oct 24, 2016

@Melkij

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

teohhanhui commented on Oct 25, 2016

@teohhanhui

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

garex

garex commented on Oct 25, 2016

@garex

@teohhanhui see my PR #2490

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

49 remaining items

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @beberlei@morozov@garex@antonmedv@Ocramius

        Issue actions

          DBAL-1168: Schema's getMigrateFromSql always adds CREATE SCHEMA · Issue #1110 · doctrine/dbal