---
tool: bin/migrate_memory.py
sha1: e492e91138f8
mtime_utc: 2026-07-19T03:04:59.625074+00:00
generated_utc: 2026-07-19T19:29:22.716448+00:00
private: false
---

# bin/migrate_memory.py

## Purpose

Migration runner for the m3-memory SQLite databases.

Supports multiple migration targets:
    - main (agent_memory.db) — always present
    - chatlog — present when the configured chatlog DB path differs from main

Subcommands:
    status                    Show current version and pending migrations
    plan [--to N]             Preview DDL that pending migrations would run (no changes)
    up [--to N] [--dry-run]   Apply pending migrations (prompts for backup + confirmation)
    down --to N [--dry-run]   Roll back to version N (requires .down.sql files)
    backup [--out PATH]       Take a standalone backup
    restore <PATH>            Restore the database from a backup file

All subcommands accept --target {main,chatlog,all} to select which DB(s) to operate on.
Default is "all" (operates on all configured targets).

Migration file formats (both supported, sorted by numeric prefix):
    NNN_name.sql            legacy, treated as up-only
    NNN_name.up.sql         explicit up
    NNN_name.down.sql       explicit down, paired with the same NNN

The schema_versions table records applied migrations. Each up/down operation
takes a filesystem-level backup of the database (including -wal/-shm) before
running, so operations are reversible at the file level even if the in-DB
transaction already committed.

---

## Entry points

- `def main()` (line 954)
- `if __name__ == "__main__"` guard

---

## CLI flags / arguments

| Flag(s) | Help | Default | Default behavior | Type/Action | Impact when set |
|---|---|---|---|---|---|
| `--database` | Override the file path for the 'main' (core memories) target. Sets M3_DATABASE for this run; targets() resolves the main DB via that env. The 'chatlog' target is unaffected — to override the chatlog DB path, set M3_CHATLOG_DATABASE in the environment before running. Default main DB: memory/agent_memory.db. | None | Falls back to M3_DATABASE env then memory/agent_memory.db. | str | Routes all DB reads/writes against PATH for this run. |
| `--target` | Memory FAMILY to migrate (NOT a git branch): 'main' = core memories DB (default agent_memory.db, overridable via --database / M3_DATABASE); 'chatlog' = chatlog memories DB (default agent_chatlog.db, overridable via M3_CHATLOG_DATABASE); 'all' = both. Default: all configured. | `all` | Displays status for all configured targets (main + chatlog if available). | str | Shows status for only specified target. |
| `--to` | Apply up to this version (default: latest) | None | Applies all pending migrations up to latest available version. | int | Applies migrations up to specified version; stops before newer ones. |
| `--target` | Memory FAMILY to migrate (NOT a git branch): 'main' = core memories DB (default agent_memory.db, overridable via --database / M3_DATABASE); 'chatlog' = chatlog memories DB (default agent_chatlog.db, overridable via M3_CHATLOG_DATABASE); 'all' = both. Default: all configured. | `all` | Prompts for backup dir; applies migrations to all configured targets. | str | Applies migrations to only specified target. |
| `-y`, `--yes` | Skip confirmation prompts | `False` | Prompts user to confirm backup dir and migration execution. | store_true | Auto-selects default backup dir (~/.m3-memory/backups) and confirms migration. |
| `--dry-run` | Print the plan + DDL without applying anything | `False` | Applies changes. | store_true | Prints the plan without mutating any DB. |
| `--to` | Roll back to this version | — | Requires explicit version (no default). | int | Reverts migrations above specified version; checks for down files first. |
| `--target` | Memory FAMILY to migrate (NOT a git branch): 'main' = core memories DB (default agent_memory.db, overridable via --database / M3_DATABASE); 'chatlog' = chatlog memories DB (default agent_chatlog.db, overridable via M3_CHATLOG_DATABASE); 'all' = both. Default: all configured. | `all` | Prompts for backup dir; rolls back all configured targets. | str | Rolls back only specified target. |
| `-y`, `--yes` | Skip confirmation prompts | `False` | Prompts user to confirm backup dir and rollback execution. | store_true | Auto-selects default backup dir and confirms rollback. |
| `--dry-run` | Print the plan + DDL without reverting anything | `False` | Reverts migrations. | store_true | Prints the plan without mutating any DB. |
| `--to` | Plan up to this version (default: latest) | None | Plans all pending migrations up to latest available version. | int | Plans migrations up to specified version; stops before newer ones. |
| `--target` | Memory FAMILY to migrate (NOT a git branch): 'main' = core memories DB (default agent_memory.db, overridable via --database / M3_DATABASE); 'chatlog' = chatlog memories DB (default agent_chatlog.db, overridable via M3_CHATLOG_DATABASE); 'all' = both. Default: all configured. | `all` | Creates backup for all configured targets in backup_dir/<target>/ subdirs. | str | Creates backup for only specified target. |
| `--out` | Backup directory (overrides saved default) | None | Uses saved backup dir from .migrate_config.json; prompts if missing. | str | Uses specified directory instead of saved config; still requires confirmation if not -y. |
| `--target` | Memory FAMILY to migrate (NOT a git branch): 'main' = core memories DB (default agent_memory.db, overridable via --database / M3_DATABASE); 'chatlog' = chatlog memories DB (default agent_chatlog.db, overridable via M3_CHATLOG_DATABASE); 'all' = both. Default: all configured. | `all` | Restores main database; warns if --target all is used (ambiguous). | str | Restores only specified target; chatlog for chat log DB. |
| `-y`, `--yes` | Skip interactive prompts | `False` | Prompts user for confirmation before creating backup. | store_true | Skips confirmation; creates backup immediately. |
| `path` | Path to the backup .db file | — | Required positional argument; no default. | str | Restores from specified backup file path. |
| `--target` | Which DB target to restore (default: main; use chatlog for chat log DB) | `main` | Restores main database; warns if all is used (ambiguous). | str | Restores only specified target; chatlog for chat log DB. |
| `-y`, `--yes` | Skip confirmation | `False` | Prompts user to confirm before overwriting current DB. | store_true | Skips confirmation; proceeds directly to restore. |

---

## Environment variables read

- `M3_DATABASE`

---

## Calls INTO this repo (intra-repo imports)

- `chatlog_config (CHATLOG_MIGRATIONS_DIR, chatlog_db_path)`
- `m3_sdk (get_m3_config_root, get_m3_engine_root, get_m3_root)`
- `m3_sdk (resolve_db_path)`

---

## Calls OUT (external side-channels)

**sqlite**

- `sqlite3.connect()  → `dst`` (line 353)
- `sqlite3.connect()  → `dst`` (line 361)
- `sqlite3.connect()  → `f'file:{db_path}?mode=ro'`` (line 126)
- `sqlite3.connect()  → `target.db_path`` (line 359)
- `sqlite3.connect()  → `target.db_path`` (line 395)
- `sqlite3.connect()  → `target.db_path`` (line 593)
- `sqlite3.connect()  → `target.db_path`` (line 661)
- `sqlite3.connect()  → `target.db_path`` (line 744)
- `sqlite3.connect()  → `target.db_path`` (line 812)
- `sqlite3.connect()  → `target.db_path`` (line 852)


---

## Notable external imports

- `m3_core.paths (resolve_config_file)`
- `m3_core.paths (resolve_engine_file)`

---

## File dependencies (repo paths referenced)

- `.db`
- `.migrate_config.json`
- `agent_memory.db`

---

## Re-validation

If the `sha1` above differs from the current file's sha1, the inventory is stale — re-read the tool, confirm flags/env vars/entry-points/calls still match, and regenerate via `python bin/gen_tool_inventory.py`.
