首页 > 解决方案 > pg-promise helpers insert 插入时跳过的替代方法是什么?

问题描述

我正在使用 pg-promise 通过 helpers.insert 和 helpers.update 构建插入和更新。

更新按预期工作,但我一直遇到与此问题类似的问题:pg-promise helpers : optionnal fields in insert and multiple-update

即,具有 postgresql 默认值的可选列会导致 helpers.insert 在输入数据上不存在该属性时引发错误。在更新时,这会触发跳过功能,这很好,但由于文档表明跳过不适用于插入,因此它会出错。

const input = { yup: true };

const query = this.pgp.helpers.insert(
  input,
  new this.pgp.helpers.ColumnSet(
    [
      { name: 'yup', skip: (col) => !col.exists },
      { name: 'nope', skip: (col) => !col.exists },

我想知道为什么跳过在插入时不起作用?有没有我想念的替代品?

使用 def 似乎有点冒险,因为我想使用 postgresql 默认值而不是覆盖它们。

我在互联网上四处搜寻,甚至发现@vitaly-t 在 2016 年使用跳过功能回答了相同的问题,该功能似乎随后从 helpers.insert 中删除。

所以我被困住了。如何获得适用于插入的相同跳过功能?

标签: postgresqlpg-promise

解决方案


因此,如果有人发现自己处于相同的位置,这就是我想出的:

export function column(name: string, prop?: string): IColumnConfig {
  return {
    name: name,
    prop: prop,
    skip: (col) => !col.exists,
  };
}
export function relationship(
  table: string,
  name: string,
  prop?: string,
): IColumnConfig {
  return {
    name: name,
    prop: prop,
    mod: ':raw',
    init: (col) => {
      if (!col.exists || isEmpty(col.value)) {
        return 'NULL';
      }
      return `(SELECT ${table}.id FROM ${table} WHERE ${table}.uuid = $<${col.name}>)`;
    },
    skip: (col) => !col.exists,
  };
}
    const insert =
      this.pgp.helpers.insert(
        input,
        new this.pgp.helpers.ColumnSet(
          [
            relationship('bar', 'bar', 'barID'),
            { name: 'name' },
            { name: 'is_a', prop: 'isA', def: false },
            { name: 'is_b', prop: 'isB', def: false },
            { name: 'is_c', prop: 'isC', def: false },
            relationship('baz', 'baz', 'bazID'), // optional
          ],
          { table: 'foo' },
        ),
      ) +
      `
      RETURNING ${select}
      `;

    return await this.db.one(insert, input);

我不能说这是最优雅的方法。但它对我想要实现的目标有效。


推荐阅读