6

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
7
  • If you want to do that permanently, you can change the search path for the user using alter user set ... Commented Feb 1, 2016 at 13:07
  • I don't want to. My purpose is to share a single Heroku Postgres database between 3 different apps (each one has a schema) Commented Feb 1, 2016 at 13:22
  • Then why don't you create three different users, each one with the specific schema as their default search_path? Commented Feb 1, 2016 at 13:25
  • Because I can't. Heroku provides a single database with a single user. Commented Feb 1, 2016 at 13:28
  • 1
    I don't think your use case is a good one, but the question is still valid. Commented Feb 3, 2016 at 14:53

2 Answers 2

7

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

Sign up to request clarification or add additional context in comments.

Comments

4
+50

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!

2 Comments

Thanks Fernando. It's the best answer so far, but I was looking for a less obtrusive way to switch schema. I will go with this for now.
It's the best solution I've found until now :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.