Mikro-orm: Migration - unecessary sql statements

Created on 19 Nov 2020  路  6Comments  路  Source: mikro-orm/mikro-orm

Describe the bug
Every migration in my env generates the following statements:
~~~javascript
this.addSql('alter table "core_task" drop constraint if exists "core_task_state_check";');
this.addSql('alter table "core_task" alter column "state" type int2 using ("state"::int2);');
this.addSql('alter table "core_task" drop constraint if exists "core_task_origin_check";');
this.addSql('alter table "core_task" alter column "origin" type int2 using ("origin"::int2);');

this.addSql('alter table "directory_contact" drop constraint if exists "directory_contact_book_object_id_check";');
this.addSql('alter table "directory_contact" alter column "book_object_id" type int4 using ("book_object_id"::int4);');
this.addSql('alter table "directory_contact" alter column "book_object_id" set not null;');

this.addSql('alter table "pbx_sip" drop constraint if exists "pbx_sip_status_check";');
this.addSql('alter table "pbx_sip" alter column "status" type int2 using ("status"::int2);');

this.addSql('alter table "pbx_tenant" drop constraint if exists "pbx_tenant_status_check";');
this.addSql('alter table "pbx_tenant" alter column "status" type int2 using ("status"::int2);');

~~~
These are clearly unecessary, for example core_task.state is already int2 and executing does not change anything. The bug persists since i'm using mikro-orm (4.x.x) and until now only occurs when using enums.

To Reproduce
~javascript
@Enum({ items: () => CoreTaskStateEnum, default: CoreTaskStateEnum.Queued })
state!: CoreTaskStateEnum
~

~javascript
export enum CoreTaskStateEnum {
Queued,
Running,
Waiting,
Continue,
Finished,
Failed,
Cancelled
}
~

Generate a migration after applying initial migration (metadataProvider: TsMorphMetadataProvider).

Expected behavior
No unecessary/duplicate sql statement.

Versions

| Dependency | Version |
| node | 15.2.1 |
| typescript | 4.0.5 |
| mikro-orm | 4.3.0 |
| pg | 8.5.1 | (server 12)

bug

Most helpful comment

This is most probably because you are passing the items there. The ORM tries to diff the enum items, but it is a numeric enum, you don't really need to pass items as long as you specify the column type.

This will work fine:

@Enum({ columnType: 'int2' })
state!: CoreTaskStateEnum

All 6 comments

Experiencing the same. It also generates these unnecessary migrations when specifying the columnType explicitly. e.g.

@Enum({
  items: () => CoreTaskStateEnum, 
  columnType: 'int2' // also tried 'smallint'
})
state!: CoreTaskStateEnum

Using ReflectMetadataProvider
@mikro-orm/core: 4.3.2
@mikro-orm/postgresql: 4.3.2
@mikro-orm/migrations: 4.3.2

This is most probably because you are passing the items there. The ORM tries to diff the enum items, but it is a numeric enum, you don't really need to pass items as long as you specify the column type.

This will work fine:

@Enum({ columnType: 'int2' })
state!: CoreTaskStateEnum

Let's keep this open, it should work like this automatically.

Just had another occurence of this issue:
When using

@Enum(() => StringEnum)
type!: StringEnum

with

export enum StringEnum {
  TEST= 'TEST'
}

and the String Based Enum only has 1 value, it emits:

    this.addSql('alter table "test_table" drop constraint if exists "test_table_type_check";');
    this.addSql('alter table "test_table" alter column "type" type text using ("type"::text);');
    this.addSql('alter table "test_table" add constraint "test_table_type_check" check ("type" in (\'TEST\'));');

when you add a second value it stops emitting the Migration.

If you change the enum to be like this, it stops emitting the unnecessary Migrations:

export enum StringEnum {
  TEST= 'TEST',
  ANOTHER = 'ANOTHER'
}

@visurel this issue is about numeric enums, string based enums should be well tested:

https://github.com/mikro-orm/mikro-orm/blob/master/tests/SchemaGenerator.test.ts#L289
https://github.com/mikro-orm/mikro-orm/blob/master/tests/__snapshots__/SchemaGenerator.test.ts.snap#L1495

So if you see similar issue there, it would be great to create separate reproduction for that.

Fixed in 4.3.3-dev.19, the issue was with const enums - those without explicit values.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Langstra picture Langstra  路  4Comments

kgoncharov picture kgoncharov  路  3Comments

Langstra picture Langstra  路  6Comments

farid009 picture farid009  路  4Comments

jsprw picture jsprw  路  6Comments