嗨,我写了一系列的大约50个迁移记录。
当我尝试运行eco.migrate
时,它只会首先运行,并且会出现这个奇怪的错误
** (FunctionClauseError) no function clause matching in IO.chardata_to_string/1
The following arguments were given to IO.chardata_to_string/1:
# 1
nil
Attempted function clauses (showing 2 out of 2):
def chardata_to_string(string) when is_binary(string)
def chardata_to_string(list) when is_list(list)
(elixir) lib/io.ex:461: IO.chardata_to_string/1
(elixir) lib/path.ex:677: Path.expand_home/1
(elixir) lib/path.ex:183: Path.expand/2
priv/database/migrations/20170517091807_seed_table_statuses.exs:2: Qber.Repo.Migrations.SeedTable.Statuses.import_from_csv/4
(stdlib) timer.erl:197: :timer.tc/3
(ecto) lib/ecto/migration/runner.ex:25: Ecto.Migration.Runner.run/6
(ecto) lib/ecto/migrator.ex:128: Ecto.Migrator.attempt/6
(ecto) lib/ecto/migrator.ex:72: anonymous fn/4 in Ecto.Migrator.do_up/4
(ecto) lib/ecto/adapters/sql.ex:576: anonymous fn/3 in Ecto.Adapters.SQL.do_transaction/3
(db_connection) lib/db_connection.ex:1283: DBConnection.transaction_run/4
(db_connection) lib/db_connection.ex:1207: DBConnection.run_begin/3
(db_connection) lib/db_connection.ex:798: DBConnection.transaction/3
(ecto) lib/ecto/migrator.ex:261: anonymous fn/4 in Ecto.Migrator.migrate/4
(elixir) lib/enum.ex:1327: Enum."-map/2-lists^map/1-0-"/2
(ecto) lib/mix/tasks/ecto.migrate.ex:83: anonymous fn/4 in Mix.Tasks.Ecto.Migrate.run/2
(elixir) lib/enum.ex:769: Enum."-each/2-lists^foreach/1-0-"/2
(elixir) lib/enum.ex:769: Enum.each/2
(mix) lib/mix/task.ex:331: Mix.Task.run_task/3
(mix) lib/mix/task.ex:365: Mix.Task.run_alias/3
(mix) lib/mix/task.ex:292: Mix.Task.run/2
这里是import_from_csv
。在我的笔记本电脑上工作正常。我刚刚在新的Mac上克隆了回购协议,但现在我陷入了困境。无法找出问题所在。我已经匹配了依赖版本,等等仍然没有出路。
def import_from_csv(
csv_path,
callback,
should_coonvert_empty_to_nil \\ false,
base_path \\ nil
) do
base_path =
if base_path == nil,
do: Application.get_env(:qber, :repo)[:seed_base_path],
else: base_path
(csv_path <> ".csv")
|> Path.expand(base_path)
|> File.stream!()
|> CSV.decode!(headers: true)
|> Stream.each(fn row ->
row
|> map_escap_sql(should_coonvert_empty_to_nil)
|> callback.()
end)
|> Stream.run()
end
答案 0 :(得分:2)
一般建议:请勿使用if
。永远不能。使用模式匹配。
# header clause with defaults
def import_from_csv(
csv_path,
callback,
should_coonvert_empty_to_nil \\ false,
base_path \\ nil
)
def import_from_csv(csv_path, callback, should_coonvert_empty_to_nil, nil) do
# https://hexdocs.pm/elixir/master/Map.html#get/3
base_path =
:qber
|> Application.get_env(:repo, %{})
|> Map.get(:seed_base_path, "")
import_from_csv(csv_path, callback, should_coonvert_empty_to_nil, base_path)
end
def import_from_csv(csv_path, callback, should_coonvert_empty_to_nil, base_path)
when is_binary(base_path) do
...
end
现在,逻辑已经很清晰了,并且在最后一个子句中使用了警卫is_binary
,您将得到明确的错误消息,说明出现了问题。
在您的代码中,Application.get_env(:qber, :repo)
返回一个没有:seed_base_path
键的映射/关键字。使用我的代码中上面显示的默认值。
答案 1 :(得分:0)
似乎已应用您的默认(nil
)值:
base_path \\ nil
Path.expand/2
和基础Path.expand_home/1
期望为二进制。