在迁移内部运行时,:ets.lookup(:tzdata_current_release,:release_version)上的参数错误

时间:2018-07-10 18:33:59

标签: elixir ecto tzdata

我有这段代码:

case Timex.Timezone.get(data) do
  {:error, _} = error ->
    error

  data ->
    {:ok, data}
end

将保存在数据库中的时区放入结构中。

在运行通过Ecto查询获取一些数据的迁移时,出现此错误:

  

**(ArgumentError)参数错误       (stdlib):ets.lookup(:tzdata_current_release,:release_version)       lib / tzdata / release_reader.ex:47:Tzdata.ReleaseReader.current_release_from_table / 0       lib / tzdata / release_reader.ex:14:Tzdata.ReleaseReader.simple_lookup / 1       lib / tzdata / release_reader.ex:7:Tzdata.ReleaseReader.zone_and_link_list / 0       lib / tzdata.ex:40:Tzdata.zone_exists?/ 1       lib / timezone / timezone.ex:152:Timex.Timezone.name_of / 1       lib / timezone / timezone.ex:180:Timex.Timezone.get / 2       lib / common / ecto / timezone.ex:27:Common.Ecto.Timezone.load / 1       (外部)lib / ecto / type.ex:661:Ecto.Type.process_loaders / 3       (外部)lib / ecto / schema.ex:1490:Ecto.Schema.load!/ 5       (外部)lib / ecto / schema.ex:1442:Ecto.Schema.safe_load_zip / 4       (外部)lib / ecto / schema.ex:1443:Ecto.Schema.safe_load_zip / 4       (ecto)lib / ecto / schema.ex:1430:Ecto.Schema。安全负载 / 6       (外部)lib / ecto / repo / queryable.ex:282:Ecto.Repo.Queryable.process_source / 6       (外部)lib / ecto / repo / queryable.ex:170:Ecto.Repo.Queryable.preprocess / 5       (postgrex)lib / postgrex / query.ex:77:DBConnection.Query.Postgrex.Query.decode_map / 3       (postgrex)lib / postgrex / query.ex:64:DBConnection.Query.Postgrex.Query.decode / 3       (db_connection)lib / db_connection.ex:1019:DBConnection.decode / 6       (外部)lib / ecto / adapters / postgres / connection.ex:73:Ecto.Adapters.Postgres.Connection.prepare_execute / 5       (ecto)lib / ecto / adapters / sql.ex:256:Ecto.Adapters.SQL.sql_call / 6

哪个代码在堆栈跟踪中,并且执行某些检查可以验证确实是触发错误的调用,尽管这样做:

  

iex(1)> Timex.Timezone.get(“ America / Los_Angeles”)

     

iex -S mix中有效。

1 个答案:

答案 0 :(得分:1)

发生此错误是因为Timex需要开始运行。如果在应用程序启动时将其添加到mix.exs依赖项中,通常会自动完成此操作。但是,在混合任务中,您必须手动选择要启动的应用程序。在您的自定义混合任务中,您可以确保通过Application.ensure_all_started(:timex)启动了应用程序。

在您的ecto.migrate情况下,我们无权访问实际的混合任务,因此我们需要通过在mix.exs文件中使用混合别名来提高创意:

  def project do
    [
      ...
      aliases: aliases(),
      ...
    ] 
  end


  defp aliases do
    [
      "ecto.migrate_s": ["ecto.migrate.startup", "ecto.migrate"],
    ]
  end

还有ecto.migrate.startup的任务Application.ensure_all_started(:timex)

defmodule Mix.Tasks.Ecto.Migrate.Startup do
  use Mix.Task

  def run(args) do
    Mix.shell.info("Starting apps required for ecto.migrate...")
    Application.ensure_all_started(:timex)
  end
end

现在,您应该能够运行mix ecto.migrate_s,该程序首先启动timex,然后运行您的迁移。 (这不是一个完美的解决方案,但我现在不知道其他选择)