【问题标题】:pg-promise helpers insert what is the alternative to skip on insert?pg-promise helpers insert 插入时跳过的替代方法是什么?
【发布时间】:2021-02-10 07:12:35
【问题描述】:

我正在使用 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 中删除。

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

【问题讨论】:

  • skip 逻辑不会向插入添加任何值,这就是它不用于插入的原因。它仅用于可以存在条件列的更新。对于插入,只需重用现有的 ColumnSet 对象,并使用方法 merge 重新定义这些列。
  • 嗨vitally-t,我可能遗漏了一些东西,但我的插入中有很多可选列。它们是默认为各种真/假状态的布尔值,我希望能够在输入对象中省略它们,并具有与更新相同的行为。目前我必须明确定义所有这些。它可以工作,但对于 postgresql 已经为我做的事情来说,它有很多样板。
  • 例如foo boolean NOT NULL DEFAULT false,bar boolean NOT NULL DEFAULT true,baz boolean NOT NULL DEFAULT false,
  • 您缺少的是,对于插入,值与列名列表相关联。你不能跳过一个而不是另一个。而对于更新,它只是一组分配,这就是使skip 逻辑成为可能的原因。
  • 我明白你的意思,就方法如何运作而言。我认为我仍然有一个带有跳过的单个插入的用例。所以我有一个带有布尔值、默认值和可选 fk 关系的表。我在 JS 服务方法中没有得到 fk id,我得到了一个 uuid,所以我插入了一个子选择来插入我需要的 fk。 INSERT INTO foo (a, b, c) VALUES (SELECT id FROM bar WHERE ...), ... 因为我在 fks 存在(或不存在)的地方有不同的插入,所以我不得不为每个组合。动态构建将是理想的,这就是跳过功能所提供的。

标签: postgresql pg-promise


【解决方案1】:

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

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);

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

【讨论】:

    猜你喜欢
    • 2017-04-03
    • 2019-11-12
    • 1970-01-01
    • 2017-11-15
    • 1970-01-01
    • 1970-01-01
    • 2022-12-15
    • 2021-10-07
    • 2017-06-07
    相关资源
    最近更新 更多