【问题标题】:How to use Phoenix with a different db driver than ecto? For example OrientDB如何将 Phoenix 与 ecto 不同的数据库驱动程序一起使用?例如东方数据库
【发布时间】:2015-11-05 16:37:01
【问题描述】:

由于我想连接到 OrientDB,因此我正试图围绕如何在不使用 Ecto 的情况下将 Phoenix 与不同的 DB 驱动程序一起使用。有一个名为 MarcoPolo 的二进制驱动程序,奇怪的是,我能够使用 poolboy 创建一个工作池来连接它——但不仅仅是一个简单的连接。我对 Elixir 还是很陌生。

这就是我所做的:

在 mix.exs 中定义依赖

  defp deps do
    [{:phoenix, "~> 1.0.3"},
     {:phoenix_html, "~> 2.1"},
     {:phoenix_live_reload, "~> 1.0", only: :dev},
     {:cowboy, "~> 1.0"},
     {:poolboy, "~> 1.5"},
     {:marco_polo, "~> 0.2"}
   ]
  end

在 lib/myapp/orientdb_repo.ex 中为我的 repo 创建一个模块

defmodule MyApp.OrientRepo do
  use MarcoPolo
end

在 lib/myapp.ex 中定义 worker

  def start(_type, _args) do
    import Supervisor.Spec, warn: false

    children = [
      # Start the endpoint when the application starts
      supervisor(MyApp.Endpoint, []),
      # Here you could define other workers and supervisors as children
      # worker(MyApp.Worker, [arg1, arg2, arg3]),
      worker(MyApp.OrientRepo, [user: "admin", password: "admin", connection: {:db, "database", :graph}])
    ]

    # See http://elixir-lang.org/docs/stable/elixir/Supervisor.html
    # for other strategies and supported options
    opts = [strategy: :one_for_one, name: MyApp.Supervisor]
    Supervisor.start_link(children, opts)
  end

但是当我尝试启动服务器时,它告诉我 MarcoPolo 未定义:

== Compilation error on file lib/myapp/orientdb_repo.ex ==
** (UndefinedFunctionError) undefined function: MarcoPolo.__using__/1
    MarcoPolo.__using__([])
    (stdlib) erl_eval.erl:669: :erl_eval.do_apply/6
    (elixir) lib/kernel/parallel_compiler.ex:100: anonymous fn/4 in Kernel.ParallelCompiler.spawn_compilers/8

我认为这应该是可用的,因为我包括了马可波罗。可能这是非常简单的事情,但我就是不明白......

【问题讨论】:

    标签: elixir phoenix-framework


    【解决方案1】:

    看起来马可波罗没有__using__ 宏,该宏扩展为 start_link、stop_link 和其他 GenServer 方法。

    这就是 Ecto 在 repo 中的做法 - https://github.com/elixir-lang/ecto/blob/3d39d89523eb4852725799db7eb7869715bd8c0d/lib/ecto/repo.ex#L60

    如果您想使用马可波罗,您需要自己提供

    lib/MyRepo/orient_repo.ex                                                                                                                                         
    defmodule MyRepo.OrientRepo do
      require MarcoPolo
    
      def start_link(opts\\[]) do
        MarcoPolo.start_link opts
      end
    
      #  ..and many more, take a look at GenServer
    end
    

    当你启动 worker 时,将所有参数作为一个数组传递

    worker(MyRepo.OrientRepo, [[user: "admin", password: "admin", connection: {:db, "database", :graph}]])
    

    在我的情况下,它会导致错误:

    [error] OrientDB TCP connect error (localhost:2424): connection refused
    

    因为我的电脑上没有 OrientDB。另一种选择是直接启动 MarcoPolo,就像 @whatyouhide 在 cmets 中所说的那样。

    更多关于use的详情请见:http://elixir-lang.org/getting-started/alias-require-and-import.html#use

    【讨论】:

    • 作为参考,您不需要将MarcoPolo 包装在您自己的模块中。您可以将worker(MarcoPolo, [[user: ..., ...]]) 传递给您的监督树。也就是说,是的MarcoPolo 是一个(低级)驱动程序,仍然没有适用于 Ecto 的适配器(它会)。它类似于 Postgrex(这是 Ecto 用于其 Postgres 适配器的 Postgres 驱动程序)。
    猜你喜欢
    • 2016-02-13
    • 2021-02-14
    • 2012-09-03
    • 2018-01-17
    • 2021-03-28
    • 2014-07-18
    • 1970-01-01
    • 1970-01-01
    • 2014-05-07
    相关资源
    最近更新 更多