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

Command "bin/console doctrine:schema:update --complete" also intends to drop the version table. #478

Open
AndreasA opened this issue Sep 16, 2022 · 8 comments

Comments

@AndreasA
Copy link

I just noticed that if I run

bin/console doctrine:schema:update --dump-sql --complete it outputs:
DROP TABLE doctrine_migration_versions;

If i run it, it does indeed drop the table. It is not that important as I use migrations to change the schema anyway, but it should still be excluded.

Using
doctrine/dbal: 3.4.4
doctrine/orm: 2.13.1
doctrine/doctrine-bundle: 2.7.0
doctrine/doctrine-migrations-bundle: 3.2.2

@AndreasA AndreasA changed the title Command "bin/console doctrine:schema:update --complete" also drops version table. Command "bin/console doctrine:schema:update --complete" also intends to drop the version table. Sep 16, 2022
@AndreasA
Copy link
Author

Of course, excluding the table to the schema_filter has other issues like executed migrations not being detected.

@chapterjason
Copy link

chapterjason commented Jan 17, 2023

I can approve this behavior.

symfony console doctrine:schema:update --force --no-interaction --complete --dump-sql
DROP TABLE doctrine_migration_versions;

 Updating database schema...

     1 query was executed

                                                                                                                        
 [OK] Database schema updated successfully!                                                                             
                                                                                                                        

@gjuric
Copy link

gjuric commented May 10, 2023

It seems like this is related to the --complete option being used. There is an issue regarding that created in the doctrine/migrations package: doctrine/migrations#1317

@FlyingDR
Copy link

May it be worth going in the same way (symfony/symfony#36655) as Symfony does for its Doctrine transport for Messenger and automatically add doctrine_migration_versions into schema?

@FlyingDR
Copy link

FlyingDR commented May 19, 2023

Unfortunately, it looks like filtering of the doctrine_migration_versions breaks the migration process itself because the same schema filter is applied for the migration process itself.

@FlyingDR
Copy link

FlyingDR commented May 20, 2023

I end up with this solution for Symfony 6 application:

<?php

declare(strict_types=1);

namespace App\Doctrine\Dbal\SchemaAssetFilter;

use Doctrine\DBAL\Schema\AbstractAsset;
use Doctrine\Migrations\Metadata\Storage\TableMetadataStorageConfiguration;
use Doctrine\Migrations\Tools\Console\Command\DoctrineCommand;
use Symfony\Component\Console\ConsoleEvents;
use Symfony\Component\Console\Event\ConsoleCommandEvent;
use Symfony\Component\DependencyInjection\Attribute\AutoconfigureTag;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
 * Prevent Doctrine migrations tracking table to be dropped by the Doctrine's schema tool
 */
#[AutoconfigureTag('doctrine.dbal.schema_filter')]
class DoctrineMigrationsFilter implements EventSubscriberInterface
{
    private bool $enabled = true;

    public function __invoke(AbstractAsset|string $asset): bool
    {
        if (!$this->enabled) {
            return true;
        }
        if (!class_exists(TableMetadataStorageConfiguration::class)) {
            return true;
        }
        if ($asset instanceof AbstractAsset) {
            $asset = $asset->getName();
        }
        return $asset !== (new TableMetadataStorageConfiguration())->getTableName();
    }

    public function onConsoleCommand(ConsoleCommandEvent $event): void
    {
        $command = $event->getCommand();
        if ($command === null) {
            return;
        }
        /**
         * Any console commands from the Doctrine Migrations bundle may attempt
         * to initialize migrations information storage table. Because of this
         * they should not be affected by this filter because their logic may
         * get broken since they will not "see" the table, they may try to use
         */
        if ($command instanceof DoctrineCommand) {
            $this->enabled = false;
        }
    }

    public static function getSubscribedEvents(): array
    {
        return [
            ConsoleEvents::COMMAND => 'onConsoleCommand',
        ];
    }
}

However, it is certainly a workaround and a bit hacky because it depends on the pre-collected list of console command classes where the filter should be disabled. But it works, hope it will be helpful for somebody else too.

@greg0ire
Copy link
Member

However, it is certainly a workaround and a bit hacky because it depends on the pre-collected list of console command classes where the filter should be disabled.

@FlyingDR According to your edit, this is no longer true I think 🙂

@FlyingDR
Copy link

@FlyingDR According to your edit, this is no longer true I think 🙂

@greg0ire Indeed :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants