Postgres enum in typeorm

前端 未结 4 1158
南笙
南笙 2021-02-18 18:49

In typeorm, how can I create a postgres enum type Gender as in this raw query

CREATE TYPE public.Gender AS ENUM (
    \'male\', \'female\'
);
ALTER TABL         


        
相关标签:
4条回答
  • 2021-02-18 19:21

    EDIT: This answer is still valid but a bit outdated as 0.1.0 alpha versions of TypeORM support enums for both PostgreSQL and MySQL.


    PostgreSQL has a built in enum type, but unfortunately TypeORM currently only supports it for MySQL.

    However, you could achieve a similar result with an int-type enum by using the @Column type as int and using the enum for your field type.

    enum Gender {
      Male,
      Female,
      Other
    }
    
    @Entity()
    export class Person {
        @Column('int')
        gender: Gender
    }
    

    (This approach lets you use the @IsEnum decorator from class-validator to validate the input if needed)

    You could also use string enums (available on TypeScript 2.4, check Typescript `enum` from JSON string for older versions) and if that is the case just change the data type to string instead.

    enum Gender {
      Male = 'male',
      Female = 'female',
      Other = 'other'
    }
    
    @Entity()
    export class Person {
        @Column('text')
        gender: Gender
    }
    
    0 讨论(0)
  • 2021-02-18 19:24

    As the accepted answer states, it is now supported in postgres but still buggy: Github issue, the fix will be released in the next RC probably. Meanwhile, I saw on the thread a nice solution which I even liked it more than the actual feature fully working:

    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 Gender {
      Male = 'male',
      Female = 'female',
      Other = 'other'
    }
    
    @Entity()
    @CheckEnum('person', 'gender', Gender)
    export class Person {
    
    0 讨论(0)
  • 2021-02-18 19:32

    Enum is now supported on TypeOrm for postgres

    By the docs

    enum column type is supported by postgres and mysql. There are various possible column definitions:

    Using typescript enums:

    export enum UserRole {
        ADMIN = "admin",
        EDITOR = "editor",
        GHOST = "ghost"
    }
    
    @Entity()
    export class User {
    
        @PrimaryGeneratedColumn()
        id: number;
    
        @Column({
            type: "enum",
            enum: UserRole,
            default: UserRole.GHOST
        })
        role: UserRole;
    
    }
    
    

    Using array with enum values:

    export type UserRoleType = "admin" | "editor" | "ghost",
    
    @Entity()
    export class User {
    
        @PrimaryGeneratedColumn()
        id: number;
    
        @Column({
            type: "enum",
            enum: ["admin", "editor", "ghost"],
            default: "ghost"
        })
        role: UserRoleType;
    }
    
    0 讨论(0)
  • 2021-02-18 19:32

    For Postgres, the column type should be 'text', not 'string', as string results in DataTypeNotSupportedError: Data type "string" in "" is not supported by "postgres" database.

    0 讨论(0)
提交回复
热议问题