TypeORM 中的 Postgres 枚举
Posted
技术标签:
【中文标题】TypeORM 中的 Postgres 枚举【英文标题】:Postgres enum in TypeORM 【发布时间】:2017-12-11 23:27:17 【问题描述】:在 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'
但显然这不是正确的方法,因为我收到错误消息“类型 enum 不存在”。
我也不想使用 typescript 枚举,因为它会在数据库中给我一堆 0 和 1。
【问题讨论】:
【参考方案1】:编辑:这个答案仍然有效,但有点过时,因为0.1.0
alpha 版本的 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('text')
gender: Gender
【讨论】:
【参考方案2】:正如接受的答案所述,它现在在 postgres 中得到支持,但仍然存在错误:Github issue,修复可能会在下一个 RC 中发布。同时,我在线程上看到了一个不错的解决方案,我什至喜欢它而不是实际功能完全正常工作:
fwiw 我一直在使用带有检查约束的字符串枚举。很多 比创建全新数据的实际 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】:对于 Postgres,列类型应该是“文本”,而不是“字符串”,因为字符串会导致 DataTypeNotSupportedError:“postgres”数据库不支持“”中的数据类型“string”。
【讨论】:
【参考方案4】:TypeOrm 现在支持 Enum for postgres
docs
postgres 和 mysql 支持枚举列类型。有多种可能的列定义:
使用打字稿枚举:
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;
【讨论】:
【参考方案5】:请参阅@noam steiner 的回答,但 TypeORM 会识别枚举类型而不明确提供它,所以这就足够了:
enum SomeEnum
# ...
class Entity
@Field()
@Column()
someEnumField: SomeEnum;
【讨论】:
【参考方案6】:值得一提的是,在多个实体中使用相同的枚举可能会导致奇怪的枚举缺失属性错误。我花了几个小时才弄清楚这个问题。
【讨论】:
以上是关于TypeORM 中的 Postgres 枚举的主要内容,如果未能解决你的问题,请参考以下文章
typeORM: "message": "\"postgres\" 数据库不支持 \"..." 中的数据类型 \"Obj
如何在 typeorm、postgres 中组合 3 列唯一的?