Rodeoclash
Manging migrations outside of Ecto
Has anyone had success with getting Ecto to use externally generated migration files? I have a directory of SQL files that I would like to migrate for my unit tests but loading each migration and executing it is causing problems with Postgres prepared statements due to multiple commands being in each SQL migration. My code to load the migrations is:
def up do
Path.wildcard("priv/repo/migrations/hasura/**/up.sql")
|> Enum.each(fn sql_file ->
sql = File.read!(sql_file)
execute("BEGIN; #{sql} COMMIT;")
end)
end
However, this gives me the error: cannot insert multiple commands into a prepared statement.
I’ve played around with the Ecto config (setting prepare: :unnamed) and wrapping each of the migration files in a BEGIN / COMMIT block (i.e. a transaction) without any luck.
I’ve resorted to using Mox to mock my Repo which works ok but I would like to test against the actual database.
Marked As Solved
benwilson512
Ah! yes 100%. So what Ecto does is that for each test it starts a transaction, and then all of your test data is executed within that transaction. Then at the end of the test, it just calls ROLLBACK on that transaction instead of COMMIT. So this way it doesn’t need to do any big delete of any data, because no data is ever committed.
In that cause I’d put all of that in a priv/repo/structure.sql file and then use the mix ecto.load task. So for a total reset you would mix do ecto.drop, ecto.create, ecto.load, run priv/repo/seeds.exs to drop, create, load your sql file, and run an extra seeds.
For your tests I’d do the same thing in MIX_ENV=test but just don’t run seeds.exs. From there, the normal Ecto Sandbox stuff should handle everything.
EDIT: I’d also add an ecto.migrate command after ecto.load to run any new migrations you later add, if you plan to add any.
Also Liked
benwilson512
Hey @Rodeoclash migrations already happen in a transaction so you shouldn’t need to add your own begin and commit. Have you tried simply doing execute(sql) ?
Rodeoclash
Thanks for hashing that out with me, I’ll do a test run tomorrow but I suspect this has been solved!
I appreciate the work you’ve done with Absinth too by the way - I’ve used it in a bunch of various projects in the esports space ![]()
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance









