如何使用typeorm将可为空的数据库字段设置为NULL?

Err*_*l59 11 postgresql express typescript typeorm

这似乎是一个很容易回答的问题,但找到答案似乎是不可能的。

我正在使用 Express 和 Typescript 为后端应用程序构建密码重置功能。我在数据库中使用 Postgres,在数据操作中使用 Typeorm。我的数据库中有一个包含这两列的User实体:

@Column({
    unique: true,
    nullable: true,
})
resetPasswordToken!: string;

@Column({ nullable: true, type: 'timestamp with time zone' })
resetPasswordExpiresAt!: Date;
Run Code Online (Sandbox Code Playgroud)

当用户请求密码重置令牌时,resetPasswordTokenresetPasswordExpiresAt字段都会填充所需的值。使用发送到用户电子邮件地址的令牌,用户可以重置他/她的密码。重置用户密码后,我想通过将它们设置为null来清除这两个字段:

user.resetPasswordToken = null;
user.resetPasswordExpiresAt = null;
user.save()
Run Code Online (Sandbox Code Playgroud)

但是,如果我这样做,Typescript 会抱怨我分配值的两行:

类型 'null' 不能分配给类型 'string'。

类型 'null' 不能分配给类型 'Date'。

如果我更改实体中的列以接受如下所示的null,错误就会消失:

resetPasswordToken!: string | null;
...
resetPasswordExpiresAt!: Date | null;
Run Code Online (Sandbox Code Playgroud)

但是,当我启动 Express 应用程序时,Typeorm 尝试连接到我的数据库时出现以下错误:

“postgres”数据库不支持“User.resetPasswordToken”中的数据类型“Object”。

 

如何将这些字段设置为null

Err*_*l59 21

经过一夜的休息,我设法解决了我的问题。

Typeorm 根据您在打字稿中为实体提供的变量的类型设置数据库字段的类型。Typeorm 将下面的代码转换为我的 postgres 数据库中的varchar字段,因为我在打字稿中给了它一个字符串作为类型。

@Column({
    unique: true,
    nullable: true,
})
resetPasswordToken!: string;
Run Code Online (Sandbox Code Playgroud)

这也是我的问题所在。Typeorm 接受字段的类型并尝试根据它读取的类型创建该数据库字段。虽然下面的代码是正确的,但打字稿基本上将两种类型都封装在一个对象中,而该对象是 Typeorm 正在读取的对象,导致我得到错误。

resetPasswordToken!: string | null;
Run Code Online (Sandbox Code Playgroud)

为了解决我的问题,我必须像这样明确指定数据库字段类型:

@Column({
    type: 'text',
    unique: true,
    nullable: true,
})
resetPasswordToken!: string;
Run Code Online (Sandbox Code Playgroud)

  • @superJustin,在将 `type: 'text'` 添加到列装饰器后,您可以添加 `string | null` 用于类型检查。 (5认同)

小智 10

接受的答案并不完全正确。MySQL DB 上字符串类型的默认 typeorm 转换为“varchar”。因此,如果您使用type: "text"它,将会错误地定义列。如果你想让它与默认行为兼容,你应该使用像这样的打字稿类型

@Column({
    type: String,
    unique: true,
    nullable: true,
})
resetPasswordToken!: string | null;
Run Code Online (Sandbox Code Playgroud)