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)
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.
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: