yii2 icon indicating copy to clipboard operation
yii2 copied to clipboard

./yii migrate/fresh does not drop PostgreSQL custom 'type'

Open SOHELAHMED7 opened this issue 3 years ago • 9 comments

What steps will reproduce the problem?

I have a migration file created by $ ./yii migrate/create min_name

I have in safeUp(): $this->execute("CREATE TYPE ".self::TABLE_NAME."_type AS ENUM ('github', 'gitlab', 'self-hosted-gitlab');");

I have in safeDown(): $this->execute('DROP type '.self::TABLE_NAME.'_type');

What is the expected result?

When I hit $ ./yii migrate/fresh the Pgsql type should be dropped

What do you get instead?

It is not dropped and when fresh command, apply all new migration from scratch I get an error similar to : type already exist. Cannot create it

My Suggestion

safeDown() of all migration should be also called during $ ./yii migrate/fresh or similar command. And not just only FK, tables etc should be dropped.

Additional info

Q A
Yii version 2.0.42.1
PHP version 7.4.26
Operating system Linux

SOHELAHMED7 avatar Feb 02 '22 14:02 SOHELAHMED7

migrate/fresh is only dropping FKs and tables and is not aware of any additional structures you may add to it that should be dropped as well because it's not reading the existing migrations. This is not possible with the way it works now. Maybe migrate/redo is what you are looking for.

bizley avatar Feb 02 '22 15:02 bizley

@bizley We stumbled upon this also.

Since migrate/fresh is reading the schema meta-data to get all tables, it would be nice if it could also read pgsql types and remove them, maybe with an optional parameter.

Not sure how to implement, but it would be really useful.

CC: @samdark

schmunk42 avatar Feb 03 '22 14:02 schmunk42

it would be nice if it could also read pgsql types

I think we should not just limit to type. There might be other DB custom things too along with type.

I suggest some combined operation of migrate/redo & mirgate/fresh


I tried migrate/redo but some migration return false on safeDown and it breaks. Also need to think work-around for this.

SOHELAHMED7 avatar Feb 03 '22 14:02 SOHELAHMED7

Hmm, yes, combined fresh + redo would be useful (until there is at least one unreversable migration). I'm not sure if we can provide such tool but we should discuss it. Any ideas?

bizley avatar Feb 03 '22 14:02 bizley

Yes, dropping extra things could be implemented. These will likely vary per database.

samdark avatar Feb 04 '22 13:02 samdark

easy solution is add methods like as hasTable(), hasColumn() to Migration:

public function hasTable($table)
{
    $schema = $this->db->getSchema();
    return in_array($schema->getRawTableName($table), $schema->getSchemaNames(true), true);
}

public function hasColumn($table, $column)
{
    $columns = $this->db->getTableSchema($table, true)->getColumnNames();
    return in_array(trim($column, '[]'), $columns, true);
}

WinterSilence avatar Feb 15 '22 15:02 WinterSilence

@bizley What do you suggest to implement it, I think it would be useful, also add the methods proposed by @WinterSilence, they would be of great help to build any migration and it would be easy to do so.

terabytesoftw avatar Oct 23 '23 11:10 terabytesoftw

It would be nice to have, yes.

bizley avatar Oct 23 '23 11:10 bizley

I would also add a method to check foreign keys.

  • hasTable()
  • hasColumn()
  • hasForeingKey()

What other method do we need to implement?

terabytesoftw avatar Oct 23 '23 11:10 terabytesoftw