在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。
答案 0 :(得分:16)
通过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));
});
});
});