elixir - 卡在迁移中,如何修复 IO.chardata_to_string/1

标签 elixir

您好,我编写了一系列大约 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 上克隆了 repo,现在我都被卡住了。无法弄清楚出了什么问题。我已经匹配了依赖版本等仍然没有出路。

  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

最佳答案

一般建议:不要使用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 键的映射/关键字。在我的代码中使用上面显示的默认值。

关于elixir - 卡在迁移中,如何修复 IO.chardata_to_string/1,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54311952/

相关文章:

Elixir 更改目录并运行 shell 脚本

erlang - 我怎样才能在 Elixir 中摆脱 Enum.reduce

elixir - Ecto 对嵌套关联的限制

migration - 尝试使用 ecto elixir 创建迁移时出现 Umbrella 应用程序错误

utf-8 - httpoison - 响应正文显示乱码文本而不是 html

elixir - 在phoenix框架(elixir)中更改Url以接受字符串而不是id

database - 我如何检测 Elixir Ecto 的数据库连接问题?

erlang - 在 Elixir 中声明 zip 存档内容的最佳方法是什么?

c++ - 将复杂的非原始 C++ 数据类型转换为 Erlang/Elixir 格式,以使用 NIF 导出方法

erlang - 如何实现一个函数来通知一个节点另一个节点是否退出