MySQL warning: Deprecated usage of mixed qualified and unqualified column names. #7541

Closed
opened 2026-01-22 15:53:11 +01:00 by admin · 0 comments
Owner

Originally created by @wkania on GitHub (Aug 4, 2025).

Related to PR.
My current setup consists of one database with the central schema and additional schemas (one per client). Until now, I was able to define entities in the code using the central schema. The rest did not have a defined schema — each client had a different one — and there is a single code repository.

Now, when I run doctrine:schema:validate, I get the following warning:

User Deprecated: Using unqualified names to create or reference objects in a schema that uses qualified names and lacks a default namespace configuration is deprecated.
(Schema.php:254 called by Schema.php:145, [Doctrine PR doctrine/dbal#6677](https://github.com/doctrine/dbal/pull/6677#user-content-unqualified-names), package doctrine/dbal)
  1. How can I fix this, and is it even possible?
  2. I understand that the PR fixes problems with SQL Server, but it breaks other configurations. Is there a way to maybe add a parameter that would allow mixing schemas as before?

My config and code:

// doctrine.yaml
doctrine:
  dbal:
    default_connection: default
    connections:
      default:
        host: '%database_host%'
        port: '%database_port%'
        dbname: '%database_name%'
        user: '%database_user%'
        password: '%database_password%'
        server_version: '8.0.32'
        charset: utf8mb4
        use_savepoints: true
        schema_manager_factory: App\Component\Doctrine\CustomSchemaManagerFactory
        default_table_options:
          charset: utf8mb4
          collate: utf8mb4_unicode_ci

// services.yaml
services:
  App\Component\Doctrine\CustomSchemaManager:
    autowire: true
    arguments:
      - '@doctrine.dbal.default_connection'
    tags:
      - { name: 'doctrine.dbal.schema_manager', priority: 1 }

  App\Component\Doctrine\CustomSchemaManagerFactory:
    autowire: true

// CustomSchemaManagerFactory.php
namespace App\Component\Doctrine;

use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Platforms\AbstractMySQLPlatform;
use Doctrine\DBAL\Schema\AbstractSchemaManager;
use Doctrine\DBAL\Schema\DefaultSchemaManagerFactory;
use Doctrine\DBAL\Schema\SchemaManagerFactory;

final readonly class CustomSchemaManagerFactory implements SchemaManagerFactory
{
    private SchemaManagerFactory $defaultFactory;

    public function __construct()
    {
        $this->defaultFactory = new DefaultSchemaManagerFactory();
    }

    public function createSchemaManager(Connection $connection): AbstractSchemaManager
    {
        $platform = $connection->getDatabasePlatform();
        if ($platform instanceof AbstractMySQLPlatform) {
            return new CustomSchemaManager($connection, $platform);
        }

        return $this->defaultFactory->createSchemaManager($connection);
    }
}

// CustomSchemaManager.php
namespace App\Component\Doctrine;

use Doctrine\DBAL\Exception;
use Doctrine\DBAL\Exception\DatabaseRequired;
use Doctrine\DBAL\Schema\MySQLSchemaManager;
use Doctrine\DBAL\Schema\Table;

class CustomSchemaManager extends MySQLSchemaManager
{
    public function listTables(): array
    {
        $database = $this->getDatabase(__METHOD__);

        $tables = $this->listTablesForDatabase($database);
        $centralTables = $this->listTablesForDatabase('central');
        /** @var Table $centralTable */
        foreach ($centralTables as $centralTable) {
            $name = 'central.'.$centralTable->getName();
            $tables[$name] = new Table(
                $name,
                $centralTable->getColumns(),
                $centralTable->getIndexes(),
                $centralTable->getUniqueConstraints(),
                $centralTable->getForeignKeys(),
                $centralTable->getOptions(),
            );
        }

        return $tables;
    }

    private function listTablesForDatabase(string $database): array
    {
        $tableColumnsByTable = $this->fetchTableColumnsByTable($database);
        $indexColumnsByTable = $this->fetchIndexColumnsByTable($database);
        $foreignKeyColumnsByTable = $this->fetchForeignKeyColumnsByTable($database);
        $tableOptionsByTable = $this->fetchTableOptionsByTable($database);

        $filter = $this->connection->getConfiguration()->getSchemaAssetsFilter();
        $tables = [];

        foreach ($tableColumnsByTable as $tableName => $tableColumns) {
            if (!$filter($tableName)) {
                continue;
            }

            $tables[] = new Table(
                $tableName,
                $this->_getPortableTableColumnList($tableName, $database, $tableColumns),
                $this->_getPortableTableIndexesList($indexColumnsByTable[$tableName] ?? [], $tableName),
                [],
                $this->_getPortableTableForeignKeysList($foreignKeyColumnsByTable[$tableName] ?? []),
                $tableOptionsByTable[$tableName] ?? [],
            );
        }

        return $tables;
    }

    /** @throws Exception */
    private function getDatabase(string $methodName): string
    {
        $database = $this->connection->getDatabase();

        if (null === $database) {
            throw DatabaseRequired::new($methodName);
        }

        return $database;
    }
}
Originally created by @wkania on GitHub (Aug 4, 2025). Related to [PR](https://github.com/doctrine/dbal/pull/6677). My current setup consists of one database with the `central` schema and additional schemas (one per client). Until now, I was able to define entities in the code using the `central` schema. The rest did not have a defined schema — each client had a different one — and there is a single code repository. Now, when I run doctrine:schema:validate, I get the following warning: User Deprecated: Using unqualified names to create or reference objects in a schema that uses qualified names and lacks a default namespace configuration is deprecated. (Schema.php:254 called by Schema.php:145, [Doctrine PR doctrine/dbal#6677](https://github.com/doctrine/dbal/pull/6677#user-content-unqualified-names), package doctrine/dbal) 1. How can I fix this, and is it even possible? 2. I understand that the PR fixes problems with SQL Server, but it breaks other configurations. Is there a way to maybe add a parameter that would allow mixing schemas as before? My config and code: ```yaml // doctrine.yaml doctrine: dbal: default_connection: default connections: default: host: '%database_host%' port: '%database_port%' dbname: '%database_name%' user: '%database_user%' password: '%database_password%' server_version: '8.0.32' charset: utf8mb4 use_savepoints: true schema_manager_factory: App\Component\Doctrine\CustomSchemaManagerFactory default_table_options: charset: utf8mb4 collate: utf8mb4_unicode_ci // services.yaml services: App\Component\Doctrine\CustomSchemaManager: autowire: true arguments: - '@doctrine.dbal.default_connection' tags: - { name: 'doctrine.dbal.schema_manager', priority: 1 } App\Component\Doctrine\CustomSchemaManagerFactory: autowire: true ``` ```php // CustomSchemaManagerFactory.php namespace App\Component\Doctrine; use Doctrine\DBAL\Connection; use Doctrine\DBAL\Platforms\AbstractMySQLPlatform; use Doctrine\DBAL\Schema\AbstractSchemaManager; use Doctrine\DBAL\Schema\DefaultSchemaManagerFactory; use Doctrine\DBAL\Schema\SchemaManagerFactory; final readonly class CustomSchemaManagerFactory implements SchemaManagerFactory { private SchemaManagerFactory $defaultFactory; public function __construct() { $this->defaultFactory = new DefaultSchemaManagerFactory(); } public function createSchemaManager(Connection $connection): AbstractSchemaManager { $platform = $connection->getDatabasePlatform(); if ($platform instanceof AbstractMySQLPlatform) { return new CustomSchemaManager($connection, $platform); } return $this->defaultFactory->createSchemaManager($connection); } } // CustomSchemaManager.php namespace App\Component\Doctrine; use Doctrine\DBAL\Exception; use Doctrine\DBAL\Exception\DatabaseRequired; use Doctrine\DBAL\Schema\MySQLSchemaManager; use Doctrine\DBAL\Schema\Table; class CustomSchemaManager extends MySQLSchemaManager { public function listTables(): array { $database = $this->getDatabase(__METHOD__); $tables = $this->listTablesForDatabase($database); $centralTables = $this->listTablesForDatabase('central'); /** @var Table $centralTable */ foreach ($centralTables as $centralTable) { $name = 'central.'.$centralTable->getName(); $tables[$name] = new Table( $name, $centralTable->getColumns(), $centralTable->getIndexes(), $centralTable->getUniqueConstraints(), $centralTable->getForeignKeys(), $centralTable->getOptions(), ); } return $tables; } private function listTablesForDatabase(string $database): array { $tableColumnsByTable = $this->fetchTableColumnsByTable($database); $indexColumnsByTable = $this->fetchIndexColumnsByTable($database); $foreignKeyColumnsByTable = $this->fetchForeignKeyColumnsByTable($database); $tableOptionsByTable = $this->fetchTableOptionsByTable($database); $filter = $this->connection->getConfiguration()->getSchemaAssetsFilter(); $tables = []; foreach ($tableColumnsByTable as $tableName => $tableColumns) { if (!$filter($tableName)) { continue; } $tables[] = new Table( $tableName, $this->_getPortableTableColumnList($tableName, $database, $tableColumns), $this->_getPortableTableIndexesList($indexColumnsByTable[$tableName] ?? [], $tableName), [], $this->_getPortableTableForeignKeysList($foreignKeyColumnsByTable[$tableName] ?? []), $tableOptionsByTable[$tableName] ?? [], ); } return $tables; } /** @throws Exception */ private function getDatabase(string $methodName): string { $database = $this->connection->getDatabase(); if (null === $database) { throw DatabaseRequired::new($methodName); } return $database; } }
admin added the Question label 2026-01-22 15:53:11 +01:00
admin closed this issue 2026-01-22 15:53:11 +01:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#7541