运行 迁移时在 jsonb 字段上添加索引失败

Adding index on jsonb field fail when running migration

我正在使用带有 TypeORM 的 PostgreSQL。我的 Student 实体有一个 jsonb 字段,定义如下:

@Entity('students')
export class Student {
  ...
  @Column('jsonb', { name: 'other_data', nullable: true })
  otherData: { nr?: string; hometown?: string } | null;
}

students table 最初是在没有列 other_data 的情况下创建的,但后来通过以下迁移添加:

await queryRunner.addColumns('students', [
      new TableColumn({
        name: 'other_data',
        type: 'jsonb',
        isNullable: true,
      }),
    ]);

列添加成功,我可以在 psql 控制台上看到 \d students 具有类型为 jsonb 的字段。

otherData 的内容预计是 json 包含 nrhometown 可选字段。

创建数据库 table 后,我尝试 运行 迁移以将索引添加到 otherDatanr 字段(请记住 otherDatajsonb 类型)。

这是我在 TypeORM 迁移文件中尝试的:

public async up(queryRunner: QueryRunner): Promise<void> {
    await queryRunner.query(
      `CREATE INDEX "student_nr" ON "students" USING gin (other_data -> 'nr')`
    );

当我 运行 迁移时,出现错误:

Migration "AddIndexOnOtherDataColumn1647948281597" has been failed, error: syntax error at or near "->"
query: ROLLBACK
Error during migration run:
QueryFailedError: syntax error at or near "->"
    at QueryFailedError.TypeORMError [as constructor] (/Users/john/myproj/src/error/TypeORMError.ts:7:9)
    at new QueryFailedError (/Users/john/myproj/src/error/QueryFailedError.ts:9:9)
    at PostgresQueryRunner.<anonymous> (/Users/john/myproj/src/driver/postgres/PostgresQueryRunner.ts:247:19)
    at step (/Users/john/myproj/node_modules/tslib/tslib.js:143:27)
    at Object.throw (/Users/john/myproj/node_modules/tslib/tslib.js:124:57)
    at rejected (/Users/john/myproj/node_modules/tslib/tslib.js:115:69)
    at processTicksAndRejections (node:internal/process/task_queues:96:5) {
  query: `CREATE INDEX "student_nr" ON "students" USING gin (other_data -> 'nr')`,
  parameters: undefined,
  driverError: error: syntax error at or near "->"

错误消息中值得注意的部分是 parameters: undefinederror near "->"。但是我一直在想为什么会出现这个错误,我哪里错了?

我最终通过在 other_data->'nr' 周围添加一个 () 解决了问题:

await queryRunner.query(
      `CREATE INDEX "student_nr" ON "students" USING gin ((other_data -> 'nr'))`
    );

但是,如果有经验的人可以验证我在解决问题方面是否正确,并且也很乐意对此进行更多解释,那就太好了。谢谢!