typeorm: Enum type not working in postgres

Issue type:

[ ] question [x] bug report [ ] feature request [ ] documentation issue

Database system/driver:

[ ] cordova [ ] mongodb [ ] mssql [ ] mysql / mariadb [ ] oracle [x] postgres [ ] sqlite [ ] sqljs [ ] react-native

TypeORM version:

[x] latest [ ] @next [ ] 0.2.0 (or put your version here)

Steps to reproduce or a small repository showing the problem:

type Action =
    'add' |
    'update' |
    'delete';
@Entity()
export class DatasourceAction {

    @PrimaryColumn()
    id: string;

    @Column({ name: 'name', type: 'text', unique: true })
    name: string;

    @Column({ name: 'action', type: 'enum', enum: ['add', 'update', 'delete'] })
    action: Action;
}

The SQL quarries executed are as follows

CREATE TYPE "test"."datasource_action_action_enum" AS ENUM('add', 'update', 'delete')
ALTER TABLE "test"."datasource_action" ADD "action" "datasource_action_action_enum" NOT NUL

and it errors with type “datasource_action_action_enum” does not exist

I think the the ALTER TABLE query should have been as follows. ALTER TABLE “test”.“datasource_action” ADD “action” “test”.“datasource_action_action_enum” NOT NUL

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 21
  • Comments: 17 (9 by maintainers)

Commits related to this issue

Most upvoted comments

I hit the same problem

    @Column({
        type: "enum",
        enum: Gender,
        default: Gender.NotAvailable,
    })
    public gender!: Gender;

Gender enum class

export enum Gender
{
    Male = "male",
    Female = "female",
    Other = "other",
    NotAvailable = "n/a",
}

@pleerock I added all the previous enum tests with external schema as part of the PR, I also used this by manually patching typeorm in prod, let me know how I can assist to move this forward.

this long-expected bug was fixed by @evik42 ! Will be released in @rc soon.

RolesEnum.ts

export enum RolesEnum {
  Admin = 'admin',
  Caregiver = 'caregiver'
}

User.ts entity

@Column({type: 'enum', enum: RolesEnum})
  role: string;

Worked for me as of version ^0.2.7 FYI

changes were already published

May i know when could i see this issue fixed on master?

@pleerock planned to release 0.2.8 and merge some PR’s this weekend. Not sure if that will be merged today, but we’re planning to slowly merge them all.

@Kononnable what do I need to do to get my PR checked for this?

fwiw I’ve been using string enum with check constraint. It’s a lot more flexible than actual postgres enum, which creates whole new data types in postgres index and are really hard to manage (alter table, etc.)


export function CheckEnum(tableName: string, fieldName: string, enumValue: any) {
  // Hash enum value and put it as part of constraint name so we can
  // force typeorm to generate migration for enum changes.
  const hash = crypto
    .createHash('sha1')
    .update(Object.values(enumValue).join(''))
    .digest('hex')
  return Check(
    // https://til.hashrocket.com/posts/8f87c65a0a-postgresqls-max-identifier-length-is-63-bytes
    `cke_${tableName}_${fieldName}_${hash}`.slice(0, 63),
    `${fieldName} in (${Object.values(enumValue).map(t => `'${t}'`)})`,
  )
}

And use it like so

export enum UserStatus {
  VERIFIED = 'VERIFIED',
  LOCKED = 'LOCKED',
}

@Entity()
@CheckEnum('user', 'status', UserStatus)
export class User extends TimestampableUUIDEntity {

This also seems to happen for enums mapped to integers when syncing the Entities to the database. I’m using TypeORM version 0.2.7.

For example, if we take the following enum:

enum Position {
    LEFT = 1,
    MIDDLE = 2,
    RIGHT = 3
}

Then add an enum type field with a default value to an Entity:

  @Column("enum", {
    enum: Position,
    default: Position[Position.LEFT]
  })
  position: Position;

This leads to the following error:

(node:23088) UnhandledPromiseRejectionWarning: QueryFailedError: invalid input value for enum user_position_enum: "LEFT"

If we adjust the default to the integer value:

  @Column("enum", {
    enum: Position,
    default: Position.LEFT
  })
  position: Position;

We still get an error:

(node:23198) UnhandledPromiseRejectionWarning: QueryFailedError: column "position" is of type user_position_enum but default expression is of type integer

+1, hitting the same. I think the original poster is spot on. It doesn’t seem to be using the correct schema on the query.