我正在尝试使用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
答案 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