Spaces:
Running
Running
| """CLI for backend migrations. | |
| Usage: | |
| python -m src.lib.system.migrate inventory --to cloud # merge (default) | |
| python -m src.lib.system.migrate inventory --to cloud --mode replace # destructive | |
| python -m src.lib.system.migrate vectors --to cloud | |
| python -m src.lib.system.migrate vectors --to local --mode replace | |
| Modes: | |
| merge (default, safe) Add new rows/points; existing target rows untouched. | |
| Idempotent — re-running produces the same end state. | |
| replace (destructive) Wipe target completely, then copy from source. | |
| """ | |
| from __future__ import annotations | |
| import argparse | |
| from .migration import migrate_inventory, migrate_vectors | |
| def main(argv: list[str] | None = None) -> int: | |
| ap = argparse.ArgumentParser(description="Migrate data between local and cloud backends") | |
| sub = ap.add_subparsers(dest="component", required=True) | |
| inv = sub.add_parser("inventory", help="Migrate the inventory DB (SQLite <-> Turso)") | |
| inv.add_argument("--to", required=True, choices=("local", "cloud")) | |
| inv.add_argument("--mode", default="merge", choices=("merge", "replace")) | |
| vec = sub.add_parser("vectors", help="Migrate Qdrant points (local <-> cloud)") | |
| vec.add_argument("--to", required=True, choices=("local", "cloud")) | |
| vec.add_argument("--collection", default=None, help="defaults to the active collection") | |
| vec.add_argument("--mode", default="merge", choices=("merge", "replace")) | |
| args = ap.parse_args(argv) | |
| direction = "local_to_cloud" if args.to == "cloud" else "cloud_to_local" | |
| if args.component == "inventory": | |
| report = migrate_inventory(direction, mode=args.mode) | |
| print(f"Inventory migration ({report.mode}) {direction}: " | |
| f"{report.total_rows} rows in {report.elapsed_ms} ms") | |
| for table, n in report.rows_per_table.items(): | |
| print(f" {table:20s} {n:>6}") | |
| if report.skipped_tables: | |
| print(f" skipped (log tables in merge mode): {', '.join(report.skipped_tables)}") | |
| else: | |
| report = migrate_vectors(direction, collection=args.collection, mode=args.mode) | |
| print(f"Vector migration ({report.mode}) {direction}: " | |
| f"collection {report.collection!r}, " | |
| f"{report.points} points in {report.elapsed_ms} ms") | |
| return 0 | |
| if __name__ == "__main__": | |
| raise SystemExit(main()) | |