doctrine:schema:update not working with dynamic schema names #5072

Open
opened 2026-01-22 14:57:43 +01:00 by admin · 6 comments
Owner

Originally created by @ju1ius on GitHub (Mar 30, 2016).

I use a Events::loadClassMetadata listener in order to dynamically add the schema name to my entities. I need this to do cross-db joins.

class MetadataListener
{
    public function loadClassMetadata(LoadClassMetadataEventArgs $event)
    {
        /** @var ClassMetadata $metadata */
        $metadata = $event->getClassMetadata();
        $namespace = explode('\\', $metadata->getName());
        switch ($namespace[0]) {
            case 'FooBundle':
                $metadata->setPrimaryTable(['schema' => 'foo']);
                break;
            default:
                $metadata->setPrimaryTable(['schema' => 'bar']);
                break;
        }
    }
}

However, the schema tool is now unable to detect any change. The output of the following command is always the same...

$ app/console doctrine:schema:update --dump-sql
> Nothing to update - your database is already in sync with the current entity metadata.
Originally created by @ju1ius on GitHub (Mar 30, 2016). I use a `Events::loadClassMetadata` listener in order to dynamically add the schema name to my entities. I need this to do cross-db joins. ``` php class MetadataListener { public function loadClassMetadata(LoadClassMetadataEventArgs $event) { /** @var ClassMetadata $metadata */ $metadata = $event->getClassMetadata(); $namespace = explode('\\', $metadata->getName()); switch ($namespace[0]) { case 'FooBundle': $metadata->setPrimaryTable(['schema' => 'foo']); break; default: $metadata->setPrimaryTable(['schema' => 'bar']); break; } } } ``` However, the schema tool is now unable to detect any change. The output of the following command is always the same... ``` sh $ app/console doctrine:schema:update --dump-sql > Nothing to update - your database is already in sync with the current entity metadata. ```
Author
Owner

@ju1ius commented on GitHub (Mar 30, 2016):

To be a bit more precise, when running

$ app/console doctrine:schema:update --dump-sql -vvv

The output contains queries concerning only the bar schema, nothing about foo.

SELECT
  TABLE_NAME AS `Table`,
  NON_UNIQUE AS Non_Unique,
  INDEX_NAME AS Key_name,
  SEQ_IN_INDEX AS Seq_in_index,
  COLUMN_NAME AS Column_Name,
  COLLATION AS Collation,
  CARDINALITY AS Cardinality,
  SUB_PART AS Sub_Part,
  PACKED AS Packed,
  NULLABLE AS `Null`,
  INDEX_TYPE AS Index_Type,
  COMMENT AS Comment
FROM information_schema.STATISTICS
WHERE
  TABLE_NAME = 'user'
  AND TABLE_SCHEMA = 'bar'

So it looks like the custom schema name is applied, but the schema tool does not check all the databases...

@ju1ius commented on GitHub (Mar 30, 2016): To be a bit more precise, when running ``` sh $ app/console doctrine:schema:update --dump-sql -vvv ``` The output contains queries concerning only the `bar` schema, nothing about `foo`. ``` sql SELECT TABLE_NAME AS `Table`, NON_UNIQUE AS Non_Unique, INDEX_NAME AS Key_name, SEQ_IN_INDEX AS Seq_in_index, COLUMN_NAME AS Column_Name, COLLATION AS Collation, CARDINALITY AS Cardinality, SUB_PART AS Sub_Part, PACKED AS Packed, NULLABLE AS `Null`, INDEX_TYPE AS Index_Type, COMMENT AS Comment FROM information_schema.STATISTICS WHERE TABLE_NAME = 'user' AND TABLE_SCHEMA = 'bar' ``` So it looks like the custom schema name is applied, but the schema tool does not check all the databases...
Author
Owner

@ju1ius commented on GitHub (Mar 30, 2016):

And if I set the schema_filter option to /^foo\..*$/, then it wants to create all the bar.* tables, although they already exists... 😕

@ju1ius commented on GitHub (Mar 30, 2016): And if I set the `schema_filter` option to `/^foo\..*$/`, then it wants to create all the `bar.*` tables, although they already exists... :confused:
Author
Owner

@ju1ius commented on GitHub (Mar 30, 2016):

$sm = $doctrine->getConnection()->getSchemaManager();
$sm->listDatabases(); // => ['foo', 'bar'];
foreach ($sm->listTables() as $table) {
    echo $table->getName() . "\n";
}
// => outputs only tables from 'bar' database...
@ju1ius commented on GitHub (Mar 30, 2016): ``` php $sm = $doctrine->getConnection()->getSchemaManager(); $sm->listDatabases(); // => ['foo', 'bar']; foreach ($sm->listTables() as $table) { echo $table->getName() . "\n"; } // => outputs only tables from 'bar' database... ```
Author
Owner

@core23 commented on GitHub (Oct 23, 2017):

I can confirm this issue when using something like this:

use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\Event\LoadClassMetadataEventArgs;
use Doctrine\ORM\Events;
use Doctrine\ORM\Mapping\ClassMetadataInfo;

final class LifecycleDateListener implements EventSubscriber
{
    public function getSubscribedEvents()
    {
        return array(
            Events::loadClassMetadata,
        );
    }

    public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs) : void
    {
        $classMetadata = $eventArgs->getClassMetadata();
        $traits = $classMetadata->getReflectionClass()->getTraitNames();

        if (!in_array(LifecycleDateTimeTrait::class, $traits)) {
            return;
        }

        $classMetadata->mapField(
            array(
                'type'      => 'datetime',
                'fieldName' => 'createdAt',
            )
        );
        $classMetadata->mapField(
            array(
                'type'      => 'datetime',
                'fieldName' => 'updatedAt',
            )
        );
    }
}

@core23 commented on GitHub (Oct 23, 2017): I can confirm this issue when using something like this: ```php use Doctrine\Common\EventSubscriber; use Doctrine\ORM\Event\LoadClassMetadataEventArgs; use Doctrine\ORM\Events; use Doctrine\ORM\Mapping\ClassMetadataInfo; final class LifecycleDateListener implements EventSubscriber { public function getSubscribedEvents() { return array( Events::loadClassMetadata, ); } public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs) : void { $classMetadata = $eventArgs->getClassMetadata(); $traits = $classMetadata->getReflectionClass()->getTraitNames(); if (!in_array(LifecycleDateTimeTrait::class, $traits)) { return; } $classMetadata->mapField( array( 'type' => 'datetime', 'fieldName' => 'createdAt', ) ); $classMetadata->mapField( array( 'type' => 'datetime', 'fieldName' => 'updatedAt', ) ); } } ```
Author
Owner

@core23 commented on GitHub (Oct 23, 2017):

Think I got it. You have to import the Trait in the real Entity class.

If you use something like this, it won't work:

namespace Foo\Entity;

class FooEntity extends Foo\Model\FooModel { }


namespace Foo\Model 

class FooModel
{
   use LifecycleDateTimeTrait;
}

@core23 commented on GitHub (Oct 23, 2017): Think I got it. You have to import the Trait in the real Entity class. If you use something like this, it won't work: ```php namespace Foo\Entity; class FooEntity extends Foo\Model\FooModel { } namespace Foo\Model class FooModel { use LifecycleDateTimeTrait; } ```
Author
Owner

@lcobucci commented on GitHub (Oct 26, 2017):

@ju1ius have you tried to use the schema property of @Table?

http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/annotations-reference.html#annref-table

@lcobucci commented on GitHub (Oct 26, 2017): @ju1ius have you tried to use the `schema` property of `@Table`? http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/annotations-reference.html#annref-table
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#5072