Postgres枚举类型

时间:2017-07-07 15:30:00

标签: postgresql typeorm

在typeorm中,如何在此原始查询中创建postgres枚举类型 Gender

CREATE TYPE public.Gender AS ENUM (
    'male', 'female'
);
ALTER TABLE public.person ALTER COLUMN gender TYPE public.gender USING gender::gender;

并在Entity类中使用它?

我试过了

@Entity()
export class Person {
    @Column('enum')
    gender: 'male' | 'female'
}

但显然这不是正确的方法,因为我收到错误消息“type enum 不存在”。

我也不想使用typescript enum,因为它会在数据库中给我一堆0和1。

5 个答案:

答案 0 :(得分:16)

TypeOrm现在支持Postgres枚举

通过docs

Postgres和mysql支持

enum列类型。有多种可能的列定义:

使用打字稿枚举:

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;

}

使用带有枚举值的数组:

export type UserRoleType = "admin" | "editor" | "ghost",

@Entity()
export class User {

    @PrimaryGeneratedColumn()
    id: number;

    @Column({
        type: "enum",
        enum: ["admin", "editor", "ghost"],
        default: "ghost"
    })
    role: UserRoleType;
}

答案 1 :(得分:6)

编辑:这个答案仍然有效但有点过时因为0.1.0字母版的TypeORM支持PostgreSQL和MySQL的枚举。

PostgreSQL内置了枚举类型,但遗憾的是TypeORM目前only supports it for MySQL

但是,使用@Column类型作为int并使用枚举作为字段类型,可以使用int类型枚举获得类似的结果。

enum Gender {
  Male,
  Female,
  Other
}

@Entity()
export class Person {
    @Column('int')
    gender: Gender
}

(此方法允许您根据需要使用@IsEnum decorator from class-validator验证输入)

您还可以使用字符串枚举(在TypeScript 2.4上可用,对于旧版本检查Typescript `enum` from JSON string),如果是这种情况,只需将数据类型更改为string

enum Gender {
  Male = 'male',
  Female = 'female',
  Other = 'other'
}

@Entity()
export class Person {
    @Column('string')
    gender: Gender
}

答案 2 :(得分:1)

正如公认的答案所述,postgres现在支持它,但是仍然存在错误:Github issue,此修复程序可能会在下一个RC中发布。同时,我在线程上看到了一个不错的解决方案,我甚至更喜欢它,而不是完全使用实际功能:

  

以前,我一直在使用带检查约束的字符串枚举。很多   比实际的postgres枚举更灵活,它可以创建全新的数据   类型在postgres索引中,并且真的很难管理(更改表,   等)

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}'`)})`,
  )
}
  

并像这样使用它

export enum Gender {
  Male = 'male',
  Female = 'female',
  Other = 'other'
}

@Entity()
@CheckEnum('person', 'gender', Gender)
export class Person {

答案 3 :(得分:1)

对于Postgres,列类型应为“文本”,而不是“字符串”,因为字符串会导致 DataTypeNotSupportedError:“ postgres”数据库不支持“”中的数据类型“ string”。

答案 4 :(得分:0)

请参阅@noam steiner 的回答,但 TypeORM 将识别枚举类型而不明确提供它,所以这就足够了:

var assert = require('assert');
describe('Array', function () {
    describe('#indexOf()', function () {
        it('should return -1 when the value is not present', function () {
            assert.equal(-1, [1, 2, 3].indexOf(4));
        });
    });
});