Postgres schema-tool fails to update existing uppercase tables #5100

Closed
opened 2026-01-22 14:58:16 +01:00 by admin · 1 comment
Owner

Originally created by @Steveb-p on GitHub (Apr 15, 2016).

Originally assigned to: @ostrolucky on GitHub.

Hello,

I wanted to migrate some of the existing database of an application to ease further development and ran into an issue where most of legacy tables are written in camelcase (cannot change these yet). While everything works fine when generating new tables from scratch, update (orm:schema-tool:update) fails to notice that those tables already do exist and tries to create them anyway.

While looking through Doctrine code to look how exactly schema-tool does this comparison to determine that a table already exists or not, I noticed that schema objects created from metadata and from existing database differ significantly in this particular case:

Existing:
database_schema

Metadata:
metadata_schema

Problem is Postgresql returns table names containing any uppercase characters with additional quoting, while metadata is - correctly in majority of cases, and conforming to a standard I guess - leaving them unquoted. Then during comparison quotation causes Doctrine to fail to notice that this table is already in _tables property and attempt to recreate the table, resulting in an error.

I have modified my local Doctrine library Doctrine\DBAL\Schema\PostgreSqlSchemaManager. changing

protected function _getPortableTableDefinition($table)
    {
        $schemas = $this->getExistingSchemaSearchPaths();
        $firstSchema = array_shift($schemas);

        if ($table['schema_name'] == $firstSchema) {
            return $table['table_name'];
        } else {
            return $table['schema_name'] . "." . $table['table_name'];
        }
    }

into

protected function _getPortableTableDefinition($table)
    {
        $schemas = $this->getExistingSchemaSearchPaths();
        $firstSchema = array_shift($schemas);

        $tableName = trim($table['table_name'], '"');

        if ($table['schema_name'] == $firstSchema) {
            return $tableName;
        } else {
            return $table['schema_name'] . "." . $tableName;
        }
    }

which caused the aforementioned error to disappear, and now table is updated correctly, allowing me to migrate my legacy database step by step.

I have three questions regarding this:

  1. Are there any side effects of this modification that you can spot (since I'm not an expert in Doctrine internals I might easily miss something)?
  2. Is it worth applying to Doctrine library itself, or should it be left out since it applies only to a particular use case, which is discouraged anyway (using uppercase characters in table names)?
  3. Is this solution to the issue enough and/or placed accurately, or should it be done somewhere else/differently?

Note I haven't run unit tests against it yet. I didn't break my application though, so it seems.

Originally created by @Steveb-p on GitHub (Apr 15, 2016). Originally assigned to: @ostrolucky on GitHub. Hello, I wanted to migrate some of the existing database of an application to ease further development and ran into an issue where most of legacy tables are written in camelcase (cannot change these yet). While everything works fine when generating new tables from scratch, update (`orm:schema-tool:update`) fails to notice that those tables already do exist and tries to create them anyway. While looking through Doctrine code to look how exactly schema-tool does this comparison to determine that a table already exists or not, I noticed that schema objects created from metadata and from existing database differ significantly in this particular case: Existing: ![database_schema](https://cloud.githubusercontent.com/assets/3183926/14558930/be881f86-0305-11e6-9cf9-7a90bc18be91.png) Metadata: ![metadata_schema](https://cloud.githubusercontent.com/assets/3183926/14558938/c8a4c820-0305-11e6-8bcb-4f1d0ef0c3e2.png) Problem is Postgresql returns table names containing any uppercase characters with additional quoting, while metadata is - correctly in majority of cases, and conforming to a standard I guess - leaving them unquoted. Then during comparison quotation causes Doctrine to fail to notice that this table is already in `_tables` property and attempt to recreate the table, resulting in an error. I have modified my local Doctrine library `Doctrine\DBAL\Schema\PostgreSqlSchemaManager`. changing ``` php protected function _getPortableTableDefinition($table) { $schemas = $this->getExistingSchemaSearchPaths(); $firstSchema = array_shift($schemas); if ($table['schema_name'] == $firstSchema) { return $table['table_name']; } else { return $table['schema_name'] . "." . $table['table_name']; } } ``` into ``` php protected function _getPortableTableDefinition($table) { $schemas = $this->getExistingSchemaSearchPaths(); $firstSchema = array_shift($schemas); $tableName = trim($table['table_name'], '"'); if ($table['schema_name'] == $firstSchema) { return $tableName; } else { return $table['schema_name'] . "." . $tableName; } } ``` which caused the aforementioned error to disappear, and now table is updated correctly, allowing me to migrate my legacy database step by step. I have three questions regarding this: 1. Are there any side effects of this modification that you can spot (since I'm not an expert in Doctrine internals I might easily miss something)? 2. Is it worth applying to Doctrine library itself, or should it be left out since it applies only to a particular use case, which is discouraged anyway (using uppercase characters in table names)? 3. Is this solution to the issue enough and/or placed accurately, or should it be done somewhere else/differently? Note I haven't run unit tests against it yet. I didn't break my application though, so it seems.
admin closed this issue 2026-01-22 14:58:19 +01:00
Author
Owner

@ostrolucky commented on GitHub (Aug 7, 2018):

In Doctrine 3.x, everything is quoted by default, which solves this issue

@ostrolucky commented on GitHub (Aug 7, 2018): In Doctrine 3.x, everything is quoted by default, which solves this issue
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#5100