在 Sequelize 模型中使用 Postgres 生成的列

Use Postgres generated columns in Sequelize model

我有一个 table 在数据库引擎中而不是在我的应用程序代码中生成预先计算的值是有益的。为此,我使用了 Postgres' generated column 功能。 SQL 是这样的:

ALTER TABLE "Items"
ADD "generatedValue" DOUBLE PRECISION GENERATED ALWAYS AS (
  LEAST("someCol", "someOtherCol")
) STORED;

这很好用,但我正在对这个数据库使用 Sequelize。我想找到一种方法在我的模型定义中定义此列,以便 Sequelize 查询它,而不是尝试更新该列的行值,理想情况下将创建同步列。

class Item extends Sequelize.Model {
  static init(sequelize) {
    return super.init({
      someCol: Sequelize.DOUBLE,
      someOtherColl: Sequelize.DOUBLE,
      generatedValue: // <<<--  What goes here??
    });
  }
}

如何使用 Sequelize 执行此操作?

我可以将列指定为 DOUBLE,Sequelize 将读取它,但不会在同步时正确创建列。也许有一些 post-sync 挂钩我可以使用?我正在考虑 afterSync 删除该列并使用我生成的值语句重新添加它,但我首先需要检测该列是否尚未转换,否则我会丢失数据。 (我 运行 在每次应用程序启动时同步 [没有 force: true]。)

如有任何想法或替代想法,我们将不胜感激。

在 Sequelize 支持只读字段和 GENERATED 数据类型之前,您可以使用自定义数据类型绕过 Sequelize:

const Item = sequelize.define('Item', {
  someCol: { type: DataTypes.DOUBLE },
  someOtherCol: { type: DataTypes.DOUBLE },
  generatedValue: {
    type: 'DOUBLE PRECISION GENERATED ALWAYS AS (LEAST("someCol", "someOtherCol")) STORED',
    set() {
      throw new Error('generatedValue is read-only')
    },
  },
})

这将在使用 sync() 时在 postgres 中正确生成列,并防止通过抛出错误在 javascript 中设置 generatedValue

假设 sequelize 在字段未更改时从不尝试更新字段,如 https://sequelize.org/master/manual/model-instances.html#change-awareness-of-save 中所述,那么它应该可以工作。