fix(backup): restore finds plugin tables by path, as the app loads them (#5674)

Run 9075: the restore got through schema and data, then all_metadata's
`import plugins` failed in the image, where plugins/ is a directory the app
loads by path (PLUGIN_DIRS), not an installed package. It now loads each
plugin under the loader's own module name from the bootstrap's plugin
dirs, which `steward restore` passes. A plugin whose models are already
mapped under either name is skipped rather than mapped twice.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-12 07:23:58 -04:00
co-authored by Claude Opus 5.5
parent fe51451704
commit 357bb6480d
2 changed files with 24 additions and 17 deletions
+2 -1
View File
@@ -96,7 +96,8 @@ def restore_command(ctx: click.Context, backup_file: Path, wipe: bool) -> None:
boot = load_bootstrap(Path(ctx.obj["config"]))
try:
done = asyncio.run(restore(backup_file, boot["database_url"], wipe=wipe))
done = asyncio.run(restore(backup_file, boot["database_url"], wipe=wipe,
plugin_dirs=[Path(d) for d in boot["plugin_dirs"]]))
except BackupError as exc:
raise click.ClickException(str(exc)) from None
made = done.manifest.get("created_at", "?")