Unable to configure for phoenix 1.3 app
phtrivier opened this issue · 9 comments
Goal
I'm trying to use sqlite for a phoenix 1.3 app.
I only want the test configuration to run against an in-memory db.
The dev, and production configuration should still run against postgresql.
Context
I'm using :
elixir1.4.2phoenix1.3.0-rc1ecto2.1.4phoenix_ecto 3.2.3
My application (I called it myapp in the examples) is part of an umbrella.
Setup
Here is what I've done.
- Add
sqlite_ecto2as a dependency inmix.exs:
defp deps do
[{:phoenix, "~> 1.3.0-rc"},
{:phoenix_pubsub, "~> 1.0"},
{:phoenix_ecto, "~> 3.0"},
....
{:sqlite_ecto2, "~> 2.0.0-dev.0"}]
end
- Add
sqlite_ecto2andectoas applications inmix.exs:
[mod: {MyApp, []},
applications: [:phoenix,
:phoenix_pubsub,
:phoenix_html,
...
:phoenix_ecto,
:postgrex,
...
:sqlite_ecto2, ## Added line
:ecto ## Added line
]]
end
(Note that I still start application postgrex, I don't know if that could conflict.)
- Edit configuration from
test.exs:
config :myapp, MyApp.Repo,
adapter: Sqlite.Ecto2,
database: "myapp_test"
- Keep
Repoclass as is:
defmodule MyApp.Repo do
use Ecto.Repo,
otp_app: :myapp
end
### Problem 1 : Compilation error
The project does not compile if I use Sqlite.Ecto2.
> mix test
I Compiling 1 file (.ex)
== Compilation error on file lib/myapp/repo.ex ==
** (ArgumentError) adapter Sqlite.Ecto2 was not compiled, ensure it is correct and it is included as a project dependency
lib/ecto/repo/supervisor.ex:55: Ecto.Repo.Supervisor.compile_config/2
lib/myapp/repo.ex:5: (module)
(stdlib) erl_eval.erl:670: :erl_eval.do_apply/6
Is it normal ? Am I using a wrong version ?
However, using Sqlite.Ecto, I get things to compile, but then I run into another set of problem.
Problem 2 : SQL.Sandbox error
With test.exs:
config :myapp, MyApp.Repo,
adapter: Sqlite.Ecto,
database: "myapp_test"
Then I get:
> mix test
Compiling 1 file (.ex)
** (RuntimeError) cannot configure sandbox with pool DBConnection.Poolboy.
To use the SQL Sandbox, configure your repository pool as:
pool: Ecto.Adapters.SQL.Sandbox
(ecto) lib/ecto/adapters/sql/sandbox.ex:429: Ecto.Adapters.SQL.Sandbox.mode/2
(elixir) lib/code.ex:370: Code.require_file/2
(elixir) lib/enum.ex:645: Enum."-each/2-lists^foreach/1-0-"/2
(elixir) lib/enum.ex:645: Enum.each/2
(mix) lib/mix/tasks/test.ex:229: Mix.Tasks.Test.run/1
Is it required / impossible to use the sandbox ? Is it because of the mix test task ?
Problem 3 : Connection issues
With test.exs:
config :myapp, MyApp.Repo,
adapter: Sqlite.Ecto,
database: "myapp_test",
pool: Ecto.Adapters.SQL.Sandbox
Then:
> mix test
** (CaseClauseError) no case clause matching: {:error, :invalid_message}
lib/db_connection/ownership.ex:58: DBConnection.Ownership.ownership_checkout/2
(ecto) lib/ecto/adapters/sql/sandbox.ex:477: Ecto.Adapters.SQL.Sandbox.checkout/2
(ecto) lib/mix/tasks/ecto.migrate.ex:79: anonymous fn/4 in Mix.Tasks.Ecto.Migrate.run/2
(elixir) lib/enum.ex:645: Enum."-each/2-lists^foreach/1-0-"/2
(elixir) lib/enum.ex:645: Enum.each/2
(mix) lib/mix/task.ex:294: Mix.Task.run_task/3
(mix) lib/mix/task.ex:326: Mix.Task.run_alias/3
(mix) lib/mix/task.ex:259: Mix.Task.run/2
Any idea what I'm missing ?
Just for info, as if this was not strange enough, it seems like:
- when running
mix testfrom the umbrella's root, everything works fine - when running
mix testfrom the phoenix app itself, I get the errors from above.
I don't know if this could be because db_connection is not started the same way in both cases.
Hi Pierre, thanks for giving this a try. I'm at work today and can't really take time from my workday for this, but I hope to have time this evening or weekend to give it a deeper look.
Confirmed and fixed "Problem 1." Investigating the others …
One thing to be aware of: If you use the mix ecto.create and mix ecto.migrate commands without specifying MIX_ENV=test somewhere, the ecto.create and ecto.migrate commands will run in your dev environment. Ordinarily, this wouldn't matter, but if I understand your case, you have configured dev to use Postgres and test to use SQLite.
Given that, you will need to be explicit about using MIX_ENV=test when doing the DB setup; otherwise, you'll have no SQLite database in place to talk to, which probably explains Problem 2 above.
Note that the default Phoenix setup aliases mix test to include the ecto.create and ecto.migrate steps, so you'll need to be explicit on every mix test invocation, thus:
MIX_ENV=test mix test
You might want to revising your mix.exs file as proposed here: elixir-lang/elixir#5462 (comment) and corrected here: elixir-lang/elixir#5462 (comment)
I am working up a release now that will address one related issue that I uncovered while attempting to repro.
@phtrivier just released 2.0.0-dev.2 on hex.pm. Please give that a try and let me know what you find.
FYI I renamed the adapter to Sqlite.Ecto2 so you will need to update that in your config files.
Also, FWIW I will be out for the rest of today (US Pacific time). Should be able to follow up later tomorrow if there are new issues.
I set up a test repo at https://github.com/scouten/phx_sqlite_ecto2 for doing my tests; if you have any remaining issues, it would be helpful to note any important differences between my test repo and your environment. (A PR on that repo would be welcome if you want to influence how I test.)
@scouten Hi, this seems to work as I want in the test environment. However, as you mentioned, in dev environment, running mix test still uses the dev db at application startup, which breaks my solution.
I'll discuss that with my team, that leaves us with three options :
- Expect everyone to start a postgres DB (
dockerworks fine for that) - Expect everyone to run tests with
MIX_ENV=test mix test - Use an
sqliteDB in bothdevandtestenvs, so thatmix testalways work.
Anyway, thanks for the help !
Closing this as resolved for now. Please feel free to reopen or file new issues if you have new issues.