Skip to content

Commit 9662cda

Browse files
abrookinsclaude
andcommitted
Separate legacy and new migration CLIs
The legacy 'migrate' command now uses automatic migrations with deprecation warnings pointing users to 'om migrate' for the new file-based system. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent 5fd01cf commit 9662cda

File tree

2 files changed

+122
-1
lines changed

2 files changed

+122
-1
lines changed

aredis_om/model/cli/legacy_migrate.py

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
import asyncio
2+
import os
3+
import warnings
4+
from typing import Optional
5+
6+
import click
7+
8+
from ...settings import get_root_migrations_dir
9+
from ..migrations.migrator import Migrator
10+
11+
12+
def run_async(coro):
13+
"""Run an async coroutine in an isolated event loop to avoid interfering with pytest loops."""
14+
import concurrent.futures
15+
16+
with concurrent.futures.ThreadPoolExecutor() as executor:
17+
future = executor.submit(asyncio.run, coro)
18+
return future.result()
19+
20+
21+
def show_deprecation_warning():
22+
"""Show deprecation warning for the legacy migrate command."""
23+
warnings.warn(
24+
"The 'migrate' command is deprecated. Please use 'om migrate' for the new file-based migration system with rollback support.",
25+
DeprecationWarning,
26+
stacklevel=3,
27+
)
28+
click.echo(
29+
click.style(
30+
"⚠️ DEPRECATED: The 'migrate' command uses automatic migrations. "
31+
"Use 'om migrate' for the new file-based system with rollback support.",
32+
fg="yellow",
33+
),
34+
err=True,
35+
)
36+
37+
38+
@click.group()
39+
def migrate():
40+
"""[DEPRECATED] Automatic schema migrations for Redis OM models. Use 'om migrate' instead."""
41+
show_deprecation_warning()
42+
43+
44+
@migrate.command()
45+
@click.option("--module", help="Python module to scan for models")
46+
def status(module: Optional[str]):
47+
"""Show pending automatic migrations (no file-based tracking)."""
48+
migrator = Migrator(module=module)
49+
50+
async def _status():
51+
await migrator.detect_migrations()
52+
return migrator.migrations
53+
54+
migrations = run_async(_status())
55+
56+
if not migrations:
57+
click.echo("No pending automatic migrations detected.")
58+
return
59+
60+
click.echo("Pending Automatic Migrations:")
61+
for migration in migrations:
62+
action = "CREATE" if migration.action.name == "CREATE" else "DROP"
63+
click.echo(f" {action}: {migration.index_name} (model: {migration.model_name})")
64+
65+
66+
@migrate.command()
67+
@click.option("--module", help="Python module to scan for models")
68+
@click.option(
69+
"--dry-run", is_flag=True, help="Show what would be done without applying changes"
70+
)
71+
@click.option("--verbose", "-v", is_flag=True, help="Enable verbose output")
72+
@click.option(
73+
"--yes",
74+
"-y",
75+
is_flag=True,
76+
help="Skip confirmation prompt to run automatic migrations",
77+
)
78+
def run(
79+
module: Optional[str],
80+
dry_run: bool,
81+
verbose: bool,
82+
yes: bool,
83+
):
84+
"""Run automatic schema migrations (immediate DROP+CREATE)."""
85+
migrator = Migrator(module=module)
86+
87+
async def _run():
88+
await migrator.detect_migrations()
89+
if not migrator.migrations:
90+
if verbose:
91+
click.echo("No pending automatic migrations found.")
92+
return 0
93+
94+
if dry_run:
95+
click.echo(f"Would run {len(migrator.migrations)} automatic migration(s):")
96+
for migration in migrator.migrations:
97+
action = "CREATE" if migration.action.name == "CREATE" else "DROP"
98+
click.echo(f" {action}: {migration.index_name}")
99+
return len(migrator.migrations)
100+
101+
if not yes:
102+
operations = []
103+
for migration in migrator.migrations:
104+
action = "CREATE" if migration.action.name == "CREATE" else "DROP"
105+
operations.append(f" {action}: {migration.index_name}")
106+
107+
if not click.confirm(
108+
f"Run {len(migrator.migrations)} automatic migration(s)?\n"
109+
+ "\n".join(operations)
110+
):
111+
click.echo("Aborted.")
112+
return 0
113+
114+
await migrator.run()
115+
if verbose:
116+
click.echo(
117+
f"Successfully applied {len(migrator.migrations)} automatic migration(s)."
118+
)
119+
return len(migrator.migrations)
120+
121+
run_async(_run())

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ pre-commit = {version = "^4.3.0", python = ">=3.9"}
7272
om = "aredis_om.cli.main:om"
7373

7474
# Backward compatibility (existing users)
75-
migrate = "redis_om.model.cli.migrate:migrate"
75+
migrate = "redis_om.model.cli.legacy_migrate:migrate"
7676

7777
[build-system]
7878
requires = ["poetry-core>=1.0.0"]

0 commit comments

Comments
 (0)