如何复制 Ecto 的记录?

asi*_*niy 4 elixir ecto

我有几张 Ecto 唱片。但我想复制它们(使它们大 100 倍)以播放大量记录。我怎样才能通过 ecto 机制做到这一点?

小智 5

您可以dup通过简单地从记录中删除 id 键来进行复制:

for n <- (0..10), do: User |> Repo.get(record_id) |> Map.delete(:id) |> Repo.insert
Run Code Online (Sandbox Code Playgroud)

虽然如果你有唯一的键那将不起作用......这会让你需要自己填充结构:

def spawn_records(line_numbers) do
  for line <- line_numbers do
    %User{first_name: "Tyrone", last_name: "Shoelaces#{line}"} |> Repo.insert
  end
end
Run Code Online (Sandbox Code Playgroud)

如果您正在考虑第二个答案,我会回应 Dogbert 并建议在 dev 中使用 ex_machina。


Don*_*ter 5

删除 :id 后,我在尝试插入时遇到了问题,因为我没有预加载关联。如果我只是复制记录,我就不必这样做,所以我想出了这个方法。这假设您将模式的必填字段和可选字段定义为模块中的常量:

@required_fields [:id, :name, :association_id]
@optional_fields [:other_field]

def duplicate(record) do
  dup = Map.take(record, @required_fields ++ @optional_fields)

  changeset(%YourModule{}, dup)
  |> Repo.insert!
end
Run Code Online (Sandbox Code Playgroud)

  • 直到 Ecto 2 在模式模块上提供了 __schema__ ,它提供了模式的运行时自省 https://hexdocs.pm/ecto/Ecto.Schema.html#module-reflection,所以你可以做类似 `fields = __MODULE__.__schema__ 的事情(:字段)` (4认同)