How to rollback a specific ecto migration?
Asked Answered
T

2

6

What is Phoenix's equivalent of Rails'?

rake db:migrate:down VERSION=20100905201547
Trophozoite answered 15/1, 2017 at 13:31 Comment(0)
T
11

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.

Trophozoite answered 15/1, 2017 at 13:48 Comment(2)
-v flag is not valid anymore. To roll back specific migration just run mix ecto.rollback 20080906120000Brachy
You can also step back, which I find to be considerably easier than finding a timestamp mix ecto.rollback --step 2Apraxia
P
1

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
Pain answered 18/12, 2018 at 3:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.