如何在Elixir Repo.Transaction中添加COPY FROM STDIN

时间:2016-08-25 10:29:46

标签: elixir ecto

我正在尝试使用Elixir Ecto,现在我需要在代码中实现COPY FROM STDIN。我在github上的postgrex.ex中找到了例子:

Postgrex.transaction(pid, fn(conn) ->
  query = Postgrex.prepare!(conn, "", "COPY posts FROM STDIN",[copy_data:true])
  stream = Postgrex.stream(conn, query, [])
  Enum.into(File.stream!("posts"), stream)
end)

我如何根据自己的需要进行转换。我必须通过什么pid?

Repo.transaction fn ->
  query = "some query"
  Ecto.Adapters.SQL.query!(Repo, query, [])
  #copy from stdin, how??
end

3 个答案:

答案 0 :(得分:4)

根据this post {+ 3}}在Elixir论坛上,应该可以:

  

可以使用运行COPY FROM STDIN   Ecto.Adapters.SQL.query!/ 4但不能使用collectable / stream:

Ecto.Adapters.SQL.query!(Repo, "COPY posts FROM STDIN",
[data_as_(final)_parameter], [copy_data: true])

..和

  

从Ecto 2.1开始,上述情况不再适用。而必须使用内置   流:

stream = Ecto.Adapters.SQL.stream(TestRepo, "COPY posts FROM STDIN")
TestRepo.transaction(fn -> Enum.into(data_enum, stream) end)

答案 1 :(得分:1)

我无法弄清楚如何用纯Ecto做到这一点,但为什么不使用Postgrex呢?您可能已经将它用作适配器。

假设您的STDIN是CSV格式的数据:

def bulk_update(data_stream, temp_table_query, copy_data_query) do
  opts = MyApp.Repo.config
  {:ok, pid} = Postgrex.start_link(opts)
  Postgrex.transaction(pid, &update_table(&1, data_stream, temp_table_query, copy_data_query))
  GenServer.stop(pid)
end

def update_table(conn, data, create_temp_table, copy_table_data) do
  Postgrex.query(conn, create_temp_table, [])
  query = Postgrex.prepare!(conn, "", "COPY incoming_data FROM STDIN DELIMITER ',' CSV", [copy_data: true])
  stream = Postgrex.stream(conn, query, [])
  Enum.into(data, stream)
  Postgrex.query(conn, copy_table_data, [])
end

答案 2 :(得分:1)

以下为我工作

round_length = rle(data1$battery_test)
data1 %>% group_by(f_device_time_date) %>% tapply(round_length$lengths,round_length$values,max)

output: 
Error in match.fun(FUN) : 
  'round_length$values' is not a function, character or symbol