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

我有一个表,其中在数据库引擎中而不是在我的应用程序代码中生成预先计算的值是有益的。为此,我使用Postgres 的生成列功能。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 将读取它,但不会在同步时正确创建该列。也许我可以使用一些同步后挂钩?我正在考虑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')
    },
  },
})

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

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


以上是在Sequelize模型中使用Postgres生成的列的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>