【问题标题】:Ecto: How to update all records with a different random numberEcto:如何使用不同的随机数更新所有记录
【发布时间】:2020-10-08 06:05:24
【问题描述】:

我在 postgresql 中有一个表,我想用随机数更新所有记录的“点”列的值。在其他语言中,我们可以遍历所有 db 记录,但是我如何使用 ecto 来做到这一点?我试过这个:

 Repo.all(from u in User, update: User.changeset(u, %{points: :rand.uniform(100)}))

但它输出以下错误:

== Compilation error in file lib/hello_remote/user.ex ==
** (Ecto.Query.CompileError) malformed update `User.changeset(u, %{points: :rand.uniform(100)})` in query expression, expected a keyword list with set/push/pop as keys with field-value pairs as values
expanding macro: Ecto.Query.update/3
lib/hello_remote/user.ex:30: HelloRemote.User.update_points/0
expanding macro: Ecto.Query.from/2
lib/hello_remote/user.ex:30: HelloRemote.User.update_points/0
(elixir 1.10.4) lib/kernel/parallel_compiler.ex:304: anonymous fn/4 in Kernel.ParallelCompiler.spawn_workers/7

我也试过这个:

from(u in User)
|> Repo.update_all(set: [points: Enum.random(0..100)])

但它会更新所有具有相同值的记录

【问题讨论】:

    标签: postgresql elixir ecto phoenix


    【解决方案1】:

    你可以使用fragment/1update_all/3,调用一个PostgreSQL函数来计算随机值,例如:

    update(User, set: [points: fragment("floor(random()*100)")])
    |> Repo.update_all([])
    

    【讨论】:

    【解决方案2】:

    我认为update_all 函数不可能。创建该函数是为了更新具有相同值的许多行。

    您可以创建一个循环并分别更新每条记录,这不是很好,而是一个可行的解决方案。

    User
    |> Repo.all()
    |> Enum.each(fn user -> update_user(user) end)
    
    def update_user(user) do
      user 
      |> Ecto.Changeset.cast(%{"points" => Enum.random(0..100)}, [:points])
      |> Repo.update!()
    end
    

    如果您想执行一次调用,您可以构建一个原始 SQL 查询并使用它。

    【讨论】:

      猜你喜欢
      • 2022-01-13
      • 2016-10-16
      • 1970-01-01
      • 2012-02-04
      • 2023-03-13
      • 2021-06-20
      • 1970-01-01
      • 1970-01-01
      • 2013-03-08
      相关资源
      最近更新 更多