【问题标题】:Elixir postgrex with poolboy example on Windows fails with 'module DBConnection.Poolboy not available'在 Windows 上带有 poolboy 示例的 Elixir postgrex 因“模块 DBConnection.Poolboy 不可用”而失败
【发布时间】:2019-05-06 08:18:17
【问题描述】:

我正在探索使用 Elixir 快速导入混合类型(CSV、JSON)的 Postgres 数据。作为 Elixir 的新手,我正在按照 youtube 视频“使用 Elixir 和 Postgrex 快速导入和导出 - Elixir Hex 包展示”(https://www.youtube.com/watch?v=YQyKRXCtq4s) 中给出的示例进行操作。基本的混合应用程序一直工作到引入 Poolboy 为止,即 Postgrex 使用单个连接成功地将记录加载到数据库中。

当我尝试遵循 Poolboy 配置并通过运行测试它时

FastIoWithPostgrex.import("./data_with_ids.txt")

在 iex 或命令行中,我收到以下错误,我无法确定原因(用户名和密码已删除):

** (UndefinedFunctionError) function DBConnection.Poolboy.child_spec/1 is 
undefined (module DBConnection.Poolboy is not available)
DBConnection.Poolboy.child_spec({Postgrex.Protocol, [types: 
Postgrex.DefaultTypes, name: :pg, pool: DBConnection.Poolboy, pool_size: 4, 
hostname: "localhost", port: 9000, username: "XXXX", password: 
"XXXX", database: "ASDDataAnalytics-DEV"]})
(db_connection) lib/db_connection.ex:383: DBConnection.start_link/2
(fast_io_with_postgrex) lib/fast_io_with_postgrex.ex:8: 
FastIoWithPostgrex.import/1

我在 Windows 10 上运行它,通过本地 SSH 隧道连接到 PostgreSQL 10.x 服务器。这是 lib/fast_io_with_postgrex.ex 文件:

defmodule FastIoWithPostgrex do
  @moduledoc """
  Documentation for FastIoWithPostgrex.
  """

  def import(filepath) do

    {:ok, pid} = Postgrex.start_link(name: :pg,
      pool: DBConnection.Poolboy,
      pool_size: 4,
      hostname: "localhost",
      port: 9000,
      username: "XXXX", password: "XXXX", database: "ASDDataAnalytics-DEV")

    File.stream!(filepath)
    |> Stream.map(fn line ->
        [id_str, word] = line |> String.trim |> String.split("\t", trim: true, parts: 2)
        {id, ""} = Integer.parse(id_str)
        [id, word]
    end)
    |> Stream.chunk_every(10_000, 10_000, [])
    |> Task.async_stream(fn word_rows ->
      Enum.each(word_rows, fn word_sql_params ->
        Postgrex.transaction(:pg, fn conn ->
          IO.inspect Postgrex.query!(conn, "INSERT INTO asdda_dataload.words (id, word) VALUES ($1, $2)", word_sql_params)
#        IO.inspect Postgrex.query!(pid, "INSERT INTO asdda_dataload.words (id, word) VALUES ($1, $2)", word_sql_params)    
        end , pool: DBConnection.Poolboy, pool_timeout: :infinity, timeout: :infinity) 
      end)
    end, timeout: :infinity)
    |> Stream.run

  end # def import(file)
end

这是 mix.exs 文件:

defmodule FastIoWithPostgrex.MixProject do
  use Mix.Project

  def project do
    [
      app: :fast_io_with_postgrex,
      version: "0.1.0",
      elixir: "~> 1.7",
      start_permanent: Mix.env() == :prod,
      deps: deps()
    ]
  end

  # Run "mix help compile.app" to learn about applications.
  def application do
    [
      extra_applications: [:logger, :poolboy, :connection]
    ]
  end

  # Run "mix help deps" to learn about dependencies.
  defp deps do
    [
      # {:dep_from_hexpm, "~> 0.3.0"},
      # {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", 
tag: "0.1.0"},

      {:postgrex, "~>0.14.1"},
      {:poolboy, "~>1.5.1"}
    ]
  end
end

这是 config/config.exs 文件:

# This file is responsible for configuring your application
# and its dependencies with the aid of the Mix.Config module.

use Mix.Config

config :fast_io_with_postgrex, :postgrex,
  database: "ASDDataAnalytics-DEV",
  username: "XXXX",
  password: "XXXX",
  name: :pg,
  pool: DBConnection.Poolboy,
  pool_size: 4

# This configuration is loaded before any dependency and is restricted
# to this project. If another project depends on this project, this
# file won't be loaded nor affect the parent project. For this reason,
# if you want to provide default values for your application for
# 3rd-party users, it should be done in your "mix.exs" file.

# You can configure your application as:
#
#     config :fast_io_with_postgrex, key: :value
#
# and access this configuration in your application as:
#
#     Application.get_env(:fast_io_with_postgrex, :key)
#
# You can also configure a 3rd-party app:
#
#     config :logger, level: :info
#

# It is also possible to import configuration files, relative to this
# directory. For example, you can emulate configuration per environment
# by uncommenting the line below and defining dev.exs, test.exs and such.
# Configuration from the imported file will override the ones defined
# here (which is why it is important to import them last).
#
#     import_config "#{Mix.env()}.exs"

我们将不胜感激任何有关查找此错误原因的帮助!

【问题讨论】:

    标签: windows-10 elixir postgrex


    【解决方案1】:

    我不想深入研究它是如何不起作用的,但是那个例子有点老了,你被deps.get 拉到的poolboy 1.5.1 来自2015.. 和例子使用 Elixir 1.4

    另外,如果你看到 Postgrex 的 mix.exs deps,你会注意到你新安装的 lib (1.14) 依赖于 elixir_ecto/db_connection 2.x

    code you are referring 使用 Postgres 1.13.x,它依赖于 {:db_connection, "~> 1.1"}。所以我预计不兼容。

    我会使用您在示例代码 mix.lock 文件中看到的库版本,如果我想看到它的工作原理,我会使用 elixir 版本。

    也许首先尝试将 Postgrex 版本降低到大约那个时候(可能在 0.12.2 和示例的锁定版本之间)。

    另外,elixir的版本在这里可能会有一些玩,请查看this

    您好!

    • 玩得开心

    编辑:

    您可以使用 DBConnection.ConnectionPool 代替 poolboy 并使用最新的 postgrex 和 elixir 版本,不确定性能差异但您可以比较,只需这样做:

    config/config.exs(检查您是否需要密码等)

    config :fast_io_with_postgrex, :postgrex,
      database: "fp",
      name: :pg,
      pool: DBConnection.ConnectionPool,
      pool_size: 4
    

    lib/fast_io_with.....ex 中,将Postgrex.start_link(... 两行替换为:

    {:ok, pid} = Application.get_env(:fast_io_with_postgrex, :postgrex)
              |> Postgrex.start_link
    

    这给了我:

    mix run -e 'FastIoWithPostgrex.import("./data_with_ids.txt")'
    1.76s user 0.69s system 106% cpu 2.294 total
    

    在 Postgrex 0.14.1 和 Elixir 1.7.3 上

    【讨论】:

      【解决方案2】:

      谢谢你,根据你的建议,我通过降级 mix.exs 文件中的依赖版本并将依赖添加到早期版本的 db_connection 来获得原始示例:

         # Run "mix help deps" to learn about dependencies.
         defp deps do
           [
             # {:dep_from_hexpm, "~> 0.3.0"},
             # {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"},
      
            {:postgrex, "0.13.5"},
            {:db_connection, "1.1.3"},
            {:poolboy, "~>1.5.1"}
       ]
       end
      

      我还将尝试您的建议,即在更高版本的 db_connection 中更改代码以将 Poolboy 替换为新的池管理器,看看是否也能正常工作。

      我确信在架构更改方面有很多想法,但是我必须说,关于为什么 Poolboy 曾经如此受欢迎的原因很少,但在最新版本的 db_connection 中甚至没有支持作为连接类型。

      【讨论】:

        猜你喜欢
        • 2014-08-06
        • 2020-05-31
        • 2019-01-21
        • 2017-12-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-04-23
        • 1970-01-01
        相关资源
        最近更新 更多