DataMigration.LiveDashboard.Page (data_migration v0.2.0)
View SourceView 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.
Running data migrations by version
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.
One-shot and repeatable data migrations
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+
Screenshots



