Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to rollback a specific ecto migration?

What is Phoenix's equivalent of Rails'?

rake db:migrate:down VERSION=20100905201547
like image 824
Jonathan Soifer Avatar asked Jan 15 '17 13:01

Jonathan Soifer


2 Answers

Currently there is no way to accomplish this.

We can rollback all the way to a specific migration using:

mix ecto.rollback -v 20080906120000

or

mix ecto.rollback --to 20080906120000

But with both syntaxes all the migrations between the current one and the specified one will be rolled back as well.

A user in the Elixir Forum also mentioned that creating a new migration that will undo what needs to be undone will be a good way to keep history accessible.

like image 160
Jonathan Soifer Avatar answered Oct 13 '22 01:10

Jonathan Soifer


This should do the trick:

def rollback(version) when is_integer(version) do
  re = ~r/^#{version}_.*\.exs/
  path = Application.app_dir(:your_app, Path.join(["priv", "repo", "migrations"]))

  with {:find, "" <> file} <- {:find, Enum.find(File.ls!(path), &String.match?(&1, re))},
        {:compile, [{mod, _} | _]} <- {:compile, Code.compile_file(Path.join(path, file))},
        {:rollback, :ok} <- {:rollback, Ecto.Migrator.down(Repo, version, mod)} do
    {:ok, "Reversed migration: #{file}"}
  else
    {:find, _} -> {:error, "No migration found with version prefix: #{version}"}
    {:compile, e} -> {:error, "Problem compiling migration module: #{inspect(e)}"}
    {:rollback, e} -> {:error, "Problem reversing migration: #{inspect(e)}"}
    e -> {:error, "Something unexpected happened: #{inspect(e)}"}
  end
end
like image 30
seanomlor Avatar answered Oct 13 '22 02:10

seanomlor