【问题标题】:Convert object array to array compatible for nodejs/pg/unnest将对象数组转换为与 nodejs/pg/unnest 兼容的数组
【发布时间】:2016-08-31 17:57:42
【问题描述】:

关于UPDATE multiple rows from multiple params in nodejs/pg,我需要运行以下命令:

update portfolios p
set votes = s.votes
from unnest(array[(5, 1), (15, 1), (25, 2)]) s (votes int, id int)
where p.id = s.id

我在unnest中的数组是$1,如下:

update portfolios p
set votes = s.votes
from unnest($1) s (votes int, id int)
where p.id = s.id

但是,我的数组最初由对象组成,如:

[{votes: 5, id: 1}, {votes: 15, id: 1}, {votes: 25, id: 2}]

我尝试将其转换为:

my_array = my_array.map(function(e) { return tuple(e.votes, e.id); });

但这失败了。

我需要使用 pg 和 Client.query 使用的值更正兼容数组。

如何转换我的对象数组以尊重 javascript 和 postgresql unnest?

【问题讨论】:

  • 你为什么需要让这个单一的update 语句发生;为什么不运行多个update 语句?
  • 我正在使用带有 pg 的 nodejs,它不支持多个查询,而无需在所有语句之间进行手动循环 - 显然。如果有其他解决方案可用,我会全力以赴。
  • 它是如何失败的?有没有办法输出正在馈送到 Postgresql 的查询?
  • 如果无法从驱动程序中获取输出,则可以在 Postgresql 日志中看到它。
  • 如果我保持 [{...}, {...}...] 格式,我会从 PostgreSQL 收到错误 42804 "enforce_generic_type_consistency"。

标签: javascript arrays node.js postgresql


【解决方案1】:

@Ziggy 传递 JSON 的想法可以工作,尽管理想的情况是让驱动程序适应您的数组。这是驱动程序必须传递给 Postgresql 的最终查询

update portfolios p
set votes = s.votes
from (
    select (a->>'votes')::int as votes, (a->>'id')::int as id
    from (
        select jsonb_array_elements(a) as a
        from (values ('[{"votes": 5, "id": 1}, {"votes": 15, "id": 1}]'::jsonb)) s(a)
    ) s
) s
where p.id = s.id

以及要传递给驱动程序的查询:

update portfolios p
set votes = s.votes
from (
    select (a->>'votes')::int as votes, (a->>'id')::int as id
    from (
        select jsonb_array_elements(a) as a
        from (values (($1)::jsonb)) s(a)
    ) s
) s
where p.id = s.id

$1 参数必须用 JSON.stringify 之类的 json 化:

var a = JSON.stringify(my_array_of_objects);

【讨论】:

    【解决方案2】:

    您可以按原样发送您的 JSON 字符串,并让 PostgreSQL 处理它:

    update portfolios p
    set votes = s.votes
    from (
      select (e->>'votes')::int as votes, (e->>'id')::int as id
      from (select (regexp_replace($1, '"\1"', 'g'))::jsonb as jarr) j
      cross join jsonb_array_elements(jarr) e
      ) s
    where p.id = s.id;
    

    其中$1[{votes: 5, id: 1}, {votes: 15, id: 1}, {votes: 25, id: 2}]', '([a-z]+) 作为字符串。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-08-03
      • 2021-09-20
      • 1970-01-01
      • 1970-01-01
      • 2021-05-03
      • 2018-12-04
      • 2021-06-16
      相关资源
      最近更新 更多