migrations icon indicating copy to clipboard operation
migrations copied to clipboard

The setting schema_filter causes migrations to fail

Open J4VMC opened this issue 6 years ago • 12 comments

Bug Report

Q A
BC Break no
Version 2.0.0

Summary

The setting schema_filter causes migrations to fail

Current behavior

When enabling the schema_filter: setting in config/packages/doctrine.yaml and running the bin/console doctrine:migrations:migrate command, it throws the error SQLSTATE[42P07]: Duplicate table: 7 ERROR: relation "migration_versions" already exists

How to reproduce

In a Symfony project with the ORM pack, add schema_filter: ~(_|^)(?!aggregate)(_|$)~ setting to config/packages/doctrine.yaml. Create a table that has aggregate in the name, make a change to an existing entity and then run bin/console doctrine:migrations:migrate.

Not 100% sure if it'd make any difference, but we're using Postgres 10.6 and we can't downgrade it to an earlier version.

Expected behavior

I'd expect Doctrine Migrations to ignore any tables matching the regular expression within the schema_filter setting

J4VMC avatar Feb 18 '19 12:02 J4VMC

Are you running any other commands before migrate? Do you have unexecuted migrations when you get the error?

jwage avatar Feb 18 '19 17:02 jwage

Are you running any other commands before migrate? Do you have unexecuted migrations when you get the error?

No, the commands I'm running are make:entity, make:migration and doctrine:migrations:migrate. No unexecuted migrations either. It also fails when generating the migration.

J4VMC avatar Feb 18 '19 21:02 J4VMC

@jwage @alcaeus I've been doing some more research on this. It fails with slightly more complex regex expressions like ~(_|^)(?!aggregate)(_|$)~, but it works fine with very simple ones like ~^(?!aggregate_)~.

I feel this issue is quite important, because in many cases people don't have the option to change the naming convention of the custom tables. Sometimes you'll have a prefix but other times it would be a keyword that you'd like to match or similar, and this case it wouldn't work.

J4VMC avatar Feb 20 '19 14:02 J4VMC

Hi!

Same problem here, even when using simpler expressions. I am using ~_translation$~ and it fails with the error:

SQLSTATE[42S01]: Base table or view already exists: 1050 Table 'migration_versions' already exists

rubenrubiob avatar Apr 18 '19 06:04 rubenrubiob

If someone can provide a failing test that would be helpful.

jwage avatar Apr 18 '19 10:04 jwage

I had the same problem and it seems to be the $ char that is problematic, removing it solve the bug

jrmgx avatar Jun 29 '19 12:06 jrmgx

Sadly it does not. Env: MySql 8 / PHP 7.3 / symfony 4.3

doctrine.yaml: doctrine: dbal: schema_filter: ~^acc_~

Running php bin/console doctrine:migrations:diff it fails with SQLSTATE[42S01]: Base table or view already exists: 1050 Table 'migration_versions' already exists

Of course, the table exists and without schema_filter migration works fine.

tmsnvd avatar Aug 09 '19 10:08 tmsnvd

Hi,

I ran on the same issue. After some digging, I found that adding migration_versions on the schema_filter solved it.

Is it possible that you also need to add the table migration_versions on the schema_filter ?

Hope it helps.

edaubert avatar Aug 21 '19 09:08 edaubert

The situation is that two are on different abstraction layers. Call it first Doctrine\DBAL\Schema\AbstractSchemaManager -> filterAssetNames function. Remove any element that is not true from regExp.

So there is no chance to solve only this in migrations lib.

icetee avatar Oct 10 '19 11:10 icetee

@jwage @alcaeus maybe doctrine/migrations should temporarily unset the asset filter configuration while checking whether the migration_versions table exists. Otherwise, things break when the migration_versions table is excluded by the filter.

stof avatar Oct 10 '19 11:10 stof

@stof yes, that's probably a sane choice. If anyone of the people involved feels comfortable creating a PR (it's Hacktoberfest after all), I'd be happy as it'll take me a while to get to it.

alcaeus avatar Oct 10 '19 12:10 alcaeus

if someone needs to allow and exclude tables in one row you can use the regexp like this: ~^(?!(api_messenger_messages|api_crm_user))(api_)~ here we allow only tables with prefix api_, but exclude some specific tables with the same prefix in the first part you exclude the tables with the same prefix then you allow all others: '~^(?!(<listOfExcludesSeparatedByPipe>))(prefixOfAllowTables)~'

maybe it will help someone :)

serrvius avatar Oct 24 '19 20:10 serrvius