postgresql - 如何使用 ecto 更新或插入多行? (更新插入)

标签 postgresql elixir ecto

如何使用 Ecto 和 Postgres 插入或更新具有不同值的多行?

如果我有一个架构/结构:%Counter{key: String.t(), count: integer()}

如何插入或更新多个条目?如果记录不存在,我想插入它,但如果它存在,我想增加该值。

[
  %{key: "questions:asked", count: 1},
  %{key: "questions:answered", count: 1},
  %{key: "ads:viewed", count: 3}
]

Ecto.Repo.insert_all 和 :on_replace 看起来应该可以工作,但我希望每行都有唯一的值。

最佳答案

您可以使用 Ecto.Repo.insert_all,但您必须提供查询并利用冲突操作中可用的 Postgresql 的 excluded 表。

upsert_query =
  Counter
  |> where([o], o.key == fragment("EXCLUDED.key"))
  |> update(inc: [count: fragment("EXCLUDED.count")])

Repo.insert_all(Counter, records,
  on_conflict: upsert_query,
  conflict_target: [:key],
  returning: false
)

排除的值是您传入的值,表示为仅在冲突时可用的临时表。

应该注意的是,如果您希望设置特定值,则可以将其与 set 一起使用,而不是 inc 。

有更好的解决方案吗?

关于postgresql - 如何使用 ecto 更新或插入多行? (更新插入),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57376729/

相关文章:

Java DBUnit AmbigouslyTableNameException 错误抛出

elixir - 管道链应该以原始值开始

elixir - 在 Ecto 中添加关系 (Phoenix 1.3)

postgresql - 将查询结果转换为hstore

mysql - 不确定的排序顺序 - MySQL 与 Postgres

erlang - 如何将 Erlang sys.config 转换为 Elixir config.exs?

range - 灵药字符范围

Elixir map 检查是否不为空且 key 存在

sql - 使用窗口函数更新表

encryption - 如何生成与 JWT 一起使用的 HS512 key