Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change Postgres search_path with Ecto

I'd like to use a specific Postgres schema for my Phoenix app.

I tried to achieve this with Ecto.Repo.after_connect/1 callback but it seems to recursively create new db connections about 10 times before timing out.

Here is my repo file :

defmodule MyApp.Repo do

  use Ecto.Repo, otp_app: :my_app
  use Scrivener, page_size: 20

  def after_connect(_pid) do
    IO.puts "after_connect"
    Ecto.Adapters.SQL.query(MyApp.Repo, "SET search_path TO 'my_app';", [])
  end

end
like image 590
Chris Avatar asked Feb 01 '16 13:02

Chris


2 Answers

I think the timeout happens because after_connect is still too early in ecto's setup cycle. Using ecto 2 (still in beta) the following works, whether it works in ecto 1 would depend on whether you get the connection as a parameter in after_connection).

In your repo:

defmodule Et.Repo do
  use Ecto.Repo, otp_app: :et

  def set_search_path(conn, path) do
    {:ok, _result} = Postgrex.query(conn, "SET search_path=#{path}", [])
  end
end

In your config.exs file:

config :et, Et.Repo,
  adapter: Ecto.Adapters.Postgres,
  database: "......",
  username: "......",
  hostname: "localhost",
  after_connect: {Et.Repo, :set_search_path, ["app,public,extensions"]}

Hope that helps, --Kip

like image 133
Kip Avatar answered Oct 03 '22 02:10

Kip


I had the same issue, and the first solution I have found was add the prefix (called schema, in postgres) in every access to my apps's Repo module. But in the recent versions of ecto and phoenix_ecto, you can modify the postgres's schema of your model just adding the attribute @schema_prefix "your_schema".

Example:

defmodule YourApp.YourModel do
  use YourApp.Web, :model

  @schema_prefix "your_schema"
  schema "your_model" do
    field :name, :string
  end

  # more stuff...
end

You can check the discussion about this feature, and another ways to solve this issue, at ecto's github: https://github.com/elixir-lang/ecto/issues/978

PS: This solve the database access for your model, but for other regular queries, you would specify prefix at your query:

%{query | prefix: "your_schema"}  

I hope I've helped!

like image 41
Fernando Gonçalves Avatar answered Oct 03 '22 03:10

Fernando Gonçalves