You're reading the main branch's readme. Please visit hexdocs for the latest published documentation.
View Ecto Data Migrations and run them from a Phoenix LiveDashboard page. Streams logs as the data migrations runs to the dashboard.
For example, in your Phoenix router:
live_dashboard "/my/admin/dashboard",
# must have `allow_destructive_actions: true` in order to run data migrations
# otherwise it will be view-only to see the status
allow_destructive_actions: true,
# Provide the page with Repo and migration folders config
additional_pages: [
# so the route becomes "/my/admin/dashboard/data_migrations"
data_migrations: {
DataMigration.LiveDashboard.Page,
{MyApp.PubSub, %{MyApp.Repo => ["data_migrations"]}, options}
# These paths will be passed into `Ecto.Migrator.migrations_path(repo, path)`
# `options` is optional; you may supply 2 item tuple instead to omit options
}
]Options you may supply to the page:
:topica different PubSub topic to listen to for capturing migration logs.:listen_for_logsA list of MFAs (tuple of length 1, 2, or 3) for which the page to listen for logs. You can also supply a module namespace, eg,MyApp.DataMigrationand any module under that namespace will have its logs listened to, egMyApp.DataMigration.FooBar. By default, the app will listen toEcto.Adapters.SQL, Ecto.Migration.Runner, andEcto.Migratorfor logs.
DataMigration.pending/2 lists the data migrations that have not run, oldest
first, and DataMigration.run/4 runs one by version, and no other:
path = Ecto.Migrator.migrations_path(MyApp.Repo, "data_migrations")
DataMigration.pending(MyApp.Repo, path)
#=> [{20260101120000, "mirror_avatars"}]
DataMigration.run(MyApp.Repo, 20260101120000, path)
#=> :okrun/4 runs nothing and returns {:error, :not_found} for a version no file
has, and {:error, :already_applied} for a one-shot data migration that has
run.
A data migration is one-shot unless it says otherwise. Mark one that is safe to
run again with use DataMigration, repeatable: true in place of
use Ecto.Migration:
defmodule MyApp.Repo.DataMigrations.MirrorAvatars do
use DataMigration, repeatable: true
def up, do: MyApp.Avatars.mirror_all()
def down, do: :ok
endEither kind is pending until it has run once. DataMigration.run/4 runs a
repeatable one again, and refuses to run a one-shot one twice. The dashboard
page's "Migrate up" still runs a data migration once.
Requires OTP 27+



