بنقرة واحدة
migrating-motoko
// Inline actor migration with (with migration = ...). Use when upgrading canister state, changing field types, or writing migration functions without the --enhanced-migration flag.
// Inline actor migration with (with migration = ...). Use when upgrading canister state, changing field types, or writing migration functions without the --enhanced-migration flag.
| name | migrating-motoko |
| description | Inline actor migration with (with migration = ...). Use when upgrading canister state, changing field types, or writing migration functions without the --enhanced-migration flag. |
Migrate actor state across canister upgrades using a migration expression attached to the actor. Each upgrade has at most one migration function.
For multi-migration with a migrations/ directory, load migrating-motoko-enhanced instead.
The runtime allows the upgrade if the new program is compatible with the old:
var ↔ let)Nat → Int)Bool → variant, Int → Float)Parenthetical expression immediately before the actor:
import Migration "migration";
(with migration = Migration.run)
actor {
var newState : Float = 0.0;
};
Or inline:
import Int "mo:core/Int";
(with migration = func(old : { var state : Int }) : { var newState : Float } {
{ var newState = old.state.toFloat() }
})
actor {
var newState : Float = 0.0;
};
Or using the shorthand when the imported module exports a migration field:
import { migration } "migration";
(with migration)
actor { ... };
func (old : { ... }) : { ... } — local, non-generic, both records must use persistable types (no functions or mutable arrays)| Field appears in | Effect |
|---|---|
| Input and output | Field is transformed |
| Output only | New field produced by migration |
| Input only | Field consumed (compiler warns about possible data loss) |
| Neither | Carried through or initialized by declaration |
Keep migrations in a separate module. Define old types inline — do not import them from old code paths:
// migration.mo
import Types "types";
import Map "mo:core/Map";
module {
type OldTask = { id : Nat; title : Text; completed : Bool };
type OldActor = {
var tasks : Map.Map<Nat, OldTask>;
var nextId : Nat;
};
type NewActor = {
var tasks : Map.Map<Nat, Types.Task>;
var nextId : Nat;
};
public func run(old : OldActor) : NewActor {
let tasks = old.tasks.map<Nat, OldTask, Types.Task>(
func(_, task) {
{
id = task.id;
title = task.title;
due = 0;
var status = if (task.completed) #completed else #pending;
}
}
);
{ var tasks; var nextId = old.nextId };
};
};
// main.mo
import Map "mo:core/Map";
import Types "types";
import Migration "migration";
(with migration = Migration.run)
actor {
var tasks = Map.empty<Nat, Types.Task>();
var nextId : Nat = 0;
};
Fields must have initializers — the migration function runs only on upgrade. On fresh install the initializers are used.
old.users.map<Nat, OldUser, NewUser>(
func(_, u) { { u with zipCode = "" } }
)
{ task with var assignee = null : ?Principal }
var status = if (task.completed) #completed else #pending;
Consume old name, produce new name:
func(old : { var state : Int }) : { var value : Int } {
{ var value = old.state }
}
Consume it in the input, omit from output. Compiler warns — ensure the loss is intentional.
migration.mofunc (old : RecordIn) : RecordOut with persistable types(with migration = Migration.run) before the actorpreupgrade/postupgrade for data migrationmops check --fix and mops buildwriting-motoko for general Motoko language referencemigrating-motoko-enhanced for multi-migration with --enhanced-migrationEnhanced multi-migration for Motoko actors. Use when writing migration files, upgrading canister state, changing actor field types, or working with the migrations/ directory and --enhanced-migration flag.
Motoko language reference, mo:core library, and architecture patterns. Use when writing, modifying, or reviewing .mo files, Motoko backend code, or canister logic.
Build the Motoko compiler (moc) and run tests in the motoko repo. Use when the user asks to build, compile, rebuild, run tests, run test-runner, or verify changes to OCaml source files.