sqlspec 0.25.0__py3-none-any.whl → 0.27.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of sqlspec might be problematic. Click here for more details.
- sqlspec/__init__.py +7 -15
- sqlspec/_serialization.py +256 -24
- sqlspec/_typing.py +71 -52
- sqlspec/adapters/adbc/_types.py +1 -1
- sqlspec/adapters/adbc/adk/__init__.py +5 -0
- sqlspec/adapters/adbc/adk/store.py +870 -0
- sqlspec/adapters/adbc/config.py +69 -12
- sqlspec/adapters/adbc/data_dictionary.py +340 -0
- sqlspec/adapters/adbc/driver.py +266 -58
- sqlspec/adapters/adbc/litestar/__init__.py +5 -0
- sqlspec/adapters/adbc/litestar/store.py +504 -0
- sqlspec/adapters/adbc/type_converter.py +153 -0
- sqlspec/adapters/aiosqlite/_types.py +1 -1
- sqlspec/adapters/aiosqlite/adk/__init__.py +5 -0
- sqlspec/adapters/aiosqlite/adk/store.py +527 -0
- sqlspec/adapters/aiosqlite/config.py +88 -15
- sqlspec/adapters/aiosqlite/data_dictionary.py +149 -0
- sqlspec/adapters/aiosqlite/driver.py +143 -40
- sqlspec/adapters/aiosqlite/litestar/__init__.py +5 -0
- sqlspec/adapters/aiosqlite/litestar/store.py +281 -0
- sqlspec/adapters/aiosqlite/pool.py +7 -7
- sqlspec/adapters/asyncmy/__init__.py +7 -1
- sqlspec/adapters/asyncmy/_types.py +2 -2
- sqlspec/adapters/asyncmy/adk/__init__.py +5 -0
- sqlspec/adapters/asyncmy/adk/store.py +493 -0
- sqlspec/adapters/asyncmy/config.py +68 -23
- sqlspec/adapters/asyncmy/data_dictionary.py +161 -0
- sqlspec/adapters/asyncmy/driver.py +313 -58
- sqlspec/adapters/asyncmy/litestar/__init__.py +5 -0
- sqlspec/adapters/asyncmy/litestar/store.py +296 -0
- sqlspec/adapters/asyncpg/__init__.py +2 -1
- sqlspec/adapters/asyncpg/_type_handlers.py +71 -0
- sqlspec/adapters/asyncpg/_types.py +11 -7
- sqlspec/adapters/asyncpg/adk/__init__.py +5 -0
- sqlspec/adapters/asyncpg/adk/store.py +450 -0
- sqlspec/adapters/asyncpg/config.py +59 -35
- sqlspec/adapters/asyncpg/data_dictionary.py +173 -0
- sqlspec/adapters/asyncpg/driver.py +170 -25
- sqlspec/adapters/asyncpg/litestar/__init__.py +5 -0
- sqlspec/adapters/asyncpg/litestar/store.py +253 -0
- sqlspec/adapters/bigquery/_types.py +1 -1
- sqlspec/adapters/bigquery/adk/__init__.py +5 -0
- sqlspec/adapters/bigquery/adk/store.py +576 -0
- sqlspec/adapters/bigquery/config.py +27 -10
- sqlspec/adapters/bigquery/data_dictionary.py +149 -0
- sqlspec/adapters/bigquery/driver.py +368 -142
- sqlspec/adapters/bigquery/litestar/__init__.py +5 -0
- sqlspec/adapters/bigquery/litestar/store.py +327 -0
- sqlspec/adapters/bigquery/type_converter.py +125 -0
- sqlspec/adapters/duckdb/_types.py +1 -1
- sqlspec/adapters/duckdb/adk/__init__.py +14 -0
- sqlspec/adapters/duckdb/adk/store.py +553 -0
- sqlspec/adapters/duckdb/config.py +80 -20
- sqlspec/adapters/duckdb/data_dictionary.py +163 -0
- sqlspec/adapters/duckdb/driver.py +167 -45
- sqlspec/adapters/duckdb/litestar/__init__.py +5 -0
- sqlspec/adapters/duckdb/litestar/store.py +332 -0
- sqlspec/adapters/duckdb/pool.py +4 -4
- sqlspec/adapters/duckdb/type_converter.py +133 -0
- sqlspec/adapters/oracledb/_numpy_handlers.py +133 -0
- sqlspec/adapters/oracledb/_types.py +20 -2
- sqlspec/adapters/oracledb/adk/__init__.py +5 -0
- sqlspec/adapters/oracledb/adk/store.py +1745 -0
- sqlspec/adapters/oracledb/config.py +122 -32
- sqlspec/adapters/oracledb/data_dictionary.py +509 -0
- sqlspec/adapters/oracledb/driver.py +353 -91
- sqlspec/adapters/oracledb/litestar/__init__.py +5 -0
- sqlspec/adapters/oracledb/litestar/store.py +767 -0
- sqlspec/adapters/oracledb/migrations.py +348 -73
- sqlspec/adapters/oracledb/type_converter.py +207 -0
- sqlspec/adapters/psqlpy/_type_handlers.py +44 -0
- sqlspec/adapters/psqlpy/_types.py +2 -1
- sqlspec/adapters/psqlpy/adk/__init__.py +5 -0
- sqlspec/adapters/psqlpy/adk/store.py +482 -0
- sqlspec/adapters/psqlpy/config.py +46 -17
- sqlspec/adapters/psqlpy/data_dictionary.py +172 -0
- sqlspec/adapters/psqlpy/driver.py +123 -209
- sqlspec/adapters/psqlpy/litestar/__init__.py +5 -0
- sqlspec/adapters/psqlpy/litestar/store.py +272 -0
- sqlspec/adapters/psqlpy/type_converter.py +102 -0
- sqlspec/adapters/psycopg/_type_handlers.py +80 -0
- sqlspec/adapters/psycopg/_types.py +2 -1
- sqlspec/adapters/psycopg/adk/__init__.py +5 -0
- sqlspec/adapters/psycopg/adk/store.py +944 -0
- sqlspec/adapters/psycopg/config.py +69 -35
- sqlspec/adapters/psycopg/data_dictionary.py +331 -0
- sqlspec/adapters/psycopg/driver.py +238 -81
- sqlspec/adapters/psycopg/litestar/__init__.py +5 -0
- sqlspec/adapters/psycopg/litestar/store.py +554 -0
- sqlspec/adapters/sqlite/__init__.py +2 -1
- sqlspec/adapters/sqlite/_type_handlers.py +86 -0
- sqlspec/adapters/sqlite/_types.py +1 -1
- sqlspec/adapters/sqlite/adk/__init__.py +5 -0
- sqlspec/adapters/sqlite/adk/store.py +572 -0
- sqlspec/adapters/sqlite/config.py +87 -15
- sqlspec/adapters/sqlite/data_dictionary.py +149 -0
- sqlspec/adapters/sqlite/driver.py +137 -54
- sqlspec/adapters/sqlite/litestar/__init__.py +5 -0
- sqlspec/adapters/sqlite/litestar/store.py +318 -0
- sqlspec/adapters/sqlite/pool.py +18 -9
- sqlspec/base.py +45 -26
- sqlspec/builder/__init__.py +73 -4
- sqlspec/builder/_base.py +162 -89
- sqlspec/builder/_column.py +62 -29
- sqlspec/builder/_ddl.py +180 -121
- sqlspec/builder/_delete.py +5 -4
- sqlspec/builder/_dml.py +388 -0
- sqlspec/{_sql.py → builder/_factory.py} +53 -94
- sqlspec/builder/_insert.py +32 -131
- sqlspec/builder/_join.py +375 -0
- sqlspec/builder/_merge.py +446 -11
- sqlspec/builder/_parsing_utils.py +111 -17
- sqlspec/builder/_select.py +1457 -24
- sqlspec/builder/_update.py +11 -42
- sqlspec/cli.py +307 -194
- sqlspec/config.py +252 -67
- sqlspec/core/__init__.py +5 -4
- sqlspec/core/cache.py +17 -17
- sqlspec/core/compiler.py +62 -9
- sqlspec/core/filters.py +37 -37
- sqlspec/core/hashing.py +9 -9
- sqlspec/core/parameters.py +83 -48
- sqlspec/core/result.py +102 -46
- sqlspec/core/splitter.py +16 -17
- sqlspec/core/statement.py +36 -30
- sqlspec/core/type_conversion.py +235 -0
- sqlspec/driver/__init__.py +7 -6
- sqlspec/driver/_async.py +188 -151
- sqlspec/driver/_common.py +285 -80
- sqlspec/driver/_sync.py +188 -152
- sqlspec/driver/mixins/_result_tools.py +20 -236
- sqlspec/driver/mixins/_sql_translator.py +4 -4
- sqlspec/exceptions.py +75 -7
- sqlspec/extensions/adk/__init__.py +53 -0
- sqlspec/extensions/adk/_types.py +51 -0
- sqlspec/extensions/adk/converters.py +172 -0
- sqlspec/extensions/adk/migrations/0001_create_adk_tables.py +144 -0
- sqlspec/extensions/adk/migrations/__init__.py +0 -0
- sqlspec/extensions/adk/service.py +181 -0
- sqlspec/extensions/adk/store.py +536 -0
- sqlspec/extensions/aiosql/adapter.py +73 -53
- sqlspec/extensions/litestar/__init__.py +21 -4
- sqlspec/extensions/litestar/cli.py +54 -10
- sqlspec/extensions/litestar/config.py +59 -266
- sqlspec/extensions/litestar/handlers.py +46 -17
- sqlspec/extensions/litestar/migrations/0001_create_session_table.py +137 -0
- sqlspec/extensions/litestar/migrations/__init__.py +3 -0
- sqlspec/extensions/litestar/plugin.py +324 -223
- sqlspec/extensions/litestar/providers.py +25 -25
- sqlspec/extensions/litestar/store.py +265 -0
- sqlspec/loader.py +30 -49
- sqlspec/migrations/__init__.py +4 -3
- sqlspec/migrations/base.py +302 -39
- sqlspec/migrations/commands.py +611 -144
- sqlspec/migrations/context.py +142 -0
- sqlspec/migrations/fix.py +199 -0
- sqlspec/migrations/loaders.py +68 -23
- sqlspec/migrations/runner.py +543 -107
- sqlspec/migrations/tracker.py +237 -21
- sqlspec/migrations/utils.py +51 -3
- sqlspec/migrations/validation.py +177 -0
- sqlspec/protocols.py +66 -36
- sqlspec/storage/_utils.py +98 -0
- sqlspec/storage/backends/fsspec.py +134 -106
- sqlspec/storage/backends/local.py +78 -51
- sqlspec/storage/backends/obstore.py +278 -162
- sqlspec/storage/registry.py +75 -39
- sqlspec/typing.py +16 -84
- sqlspec/utils/config_resolver.py +153 -0
- sqlspec/utils/correlation.py +4 -5
- sqlspec/utils/data_transformation.py +3 -2
- sqlspec/utils/deprecation.py +9 -8
- sqlspec/utils/fixtures.py +4 -4
- sqlspec/utils/logging.py +46 -6
- sqlspec/utils/module_loader.py +2 -2
- sqlspec/utils/schema.py +288 -0
- sqlspec/utils/serializers.py +50 -2
- sqlspec/utils/sync_tools.py +21 -17
- sqlspec/utils/text.py +1 -2
- sqlspec/utils/type_guards.py +111 -20
- sqlspec/utils/version.py +433 -0
- {sqlspec-0.25.0.dist-info → sqlspec-0.27.0.dist-info}/METADATA +40 -21
- sqlspec-0.27.0.dist-info/RECORD +207 -0
- sqlspec/builder/mixins/__init__.py +0 -55
- sqlspec/builder/mixins/_cte_and_set_ops.py +0 -254
- sqlspec/builder/mixins/_delete_operations.py +0 -50
- sqlspec/builder/mixins/_insert_operations.py +0 -282
- sqlspec/builder/mixins/_join_operations.py +0 -389
- sqlspec/builder/mixins/_merge_operations.py +0 -592
- sqlspec/builder/mixins/_order_limit_operations.py +0 -152
- sqlspec/builder/mixins/_pivot_operations.py +0 -157
- sqlspec/builder/mixins/_select_operations.py +0 -936
- sqlspec/builder/mixins/_update_operations.py +0 -218
- sqlspec/builder/mixins/_where_clause.py +0 -1304
- sqlspec-0.25.0.dist-info/RECORD +0 -139
- sqlspec-0.25.0.dist-info/licenses/NOTICE +0 -29
- {sqlspec-0.25.0.dist-info → sqlspec-0.27.0.dist-info}/WHEEL +0 -0
- {sqlspec-0.25.0.dist-info → sqlspec-0.27.0.dist-info}/entry_points.txt +0 -0
- {sqlspec-0.25.0.dist-info → sqlspec-0.27.0.dist-info}/licenses/LICENSE +0 -0
sqlspec/cli.py
CHANGED
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
# ruff: noqa: C901
|
|
2
|
+
import inspect
|
|
2
3
|
import sys
|
|
3
4
|
from collections.abc import Sequence
|
|
4
|
-
from
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import TYPE_CHECKING, Any, cast
|
|
7
|
+
|
|
8
|
+
import rich_click as click
|
|
5
9
|
|
|
6
10
|
if TYPE_CHECKING:
|
|
7
|
-
from
|
|
11
|
+
from rich_click import Group
|
|
8
12
|
|
|
9
13
|
from sqlspec.config import AsyncDatabaseConfig, SyncDatabaseConfig
|
|
14
|
+
from sqlspec.migrations.commands import AsyncMigrationCommands, SyncMigrationCommands
|
|
10
15
|
|
|
11
16
|
__all__ = ("add_migration_commands", "get_sqlspec_group")
|
|
12
17
|
|
|
@@ -14,72 +19,76 @@ __all__ = ("add_migration_commands", "get_sqlspec_group")
|
|
|
14
19
|
def get_sqlspec_group() -> "Group":
|
|
15
20
|
"""Get the SQLSpec CLI group.
|
|
16
21
|
|
|
17
|
-
Raises:
|
|
18
|
-
MissingDependencyError: If the `click` package is not installed.
|
|
19
|
-
|
|
20
22
|
Returns:
|
|
21
23
|
The SQLSpec CLI group.
|
|
22
24
|
"""
|
|
23
|
-
from sqlspec.exceptions import MissingDependencyError
|
|
24
|
-
|
|
25
|
-
try:
|
|
26
|
-
import rich_click as click
|
|
27
|
-
except ImportError:
|
|
28
|
-
try:
|
|
29
|
-
import click # type: ignore[no-redef]
|
|
30
|
-
except ImportError as e:
|
|
31
|
-
raise MissingDependencyError(package="click", install_package="cli") from e
|
|
32
25
|
|
|
33
26
|
@click.group(name="sqlspec")
|
|
34
27
|
@click.option(
|
|
35
28
|
"--config",
|
|
36
|
-
help="Dotted path to SQLSpec config(s) (e.g. 'myapp.config.
|
|
29
|
+
help="Dotted path to SQLSpec config(s) or callable function (e.g. 'myapp.config.get_configs')",
|
|
37
30
|
required=True,
|
|
38
31
|
type=str,
|
|
39
32
|
)
|
|
33
|
+
@click.option(
|
|
34
|
+
"--validate-config", is_flag=True, default=False, help="Validate configuration before executing migrations"
|
|
35
|
+
)
|
|
40
36
|
@click.pass_context
|
|
41
|
-
def sqlspec_group(ctx: "click.Context", config: str) -> None:
|
|
37
|
+
def sqlspec_group(ctx: "click.Context", config: str, validate_config: bool) -> None:
|
|
42
38
|
"""SQLSpec CLI commands."""
|
|
43
39
|
from rich import get_console
|
|
44
40
|
|
|
45
|
-
from sqlspec.
|
|
41
|
+
from sqlspec.exceptions import ConfigResolverError
|
|
42
|
+
from sqlspec.utils.config_resolver import resolve_config_sync
|
|
46
43
|
|
|
47
44
|
console = get_console()
|
|
48
45
|
ctx.ensure_object(dict)
|
|
46
|
+
|
|
47
|
+
# Add current working directory to sys.path to allow loading local config modules
|
|
48
|
+
cwd = str(Path.cwd())
|
|
49
|
+
cwd_added = False
|
|
50
|
+
if cwd not in sys.path:
|
|
51
|
+
sys.path.insert(0, cwd)
|
|
52
|
+
cwd_added = True
|
|
53
|
+
|
|
49
54
|
try:
|
|
50
|
-
|
|
51
|
-
if isinstance(
|
|
52
|
-
ctx.obj["configs"] =
|
|
55
|
+
config_result = resolve_config_sync(config)
|
|
56
|
+
if isinstance(config_result, Sequence) and not isinstance(config_result, str):
|
|
57
|
+
ctx.obj["configs"] = list(config_result)
|
|
53
58
|
else:
|
|
54
|
-
ctx.obj["configs"] = [
|
|
55
|
-
|
|
59
|
+
ctx.obj["configs"] = [config_result]
|
|
60
|
+
|
|
61
|
+
ctx.obj["validate_config"] = validate_config
|
|
62
|
+
|
|
63
|
+
if validate_config:
|
|
64
|
+
console.print(f"[green]✓[/] Successfully loaded {len(ctx.obj['configs'])} config(s)")
|
|
65
|
+
for i, cfg in enumerate(ctx.obj["configs"]):
|
|
66
|
+
config_name = cfg.bind_key or f"config-{i}"
|
|
67
|
+
config_type = type(cfg).__name__
|
|
68
|
+
is_async = cfg.is_async
|
|
69
|
+
execution_hint = "[dim cyan](async-capable)[/]" if is_async else "[dim](sync)[/]"
|
|
70
|
+
console.print(f" [dim]•[/] {config_name}: {config_type} {execution_hint}")
|
|
71
|
+
|
|
72
|
+
except (ImportError, ConfigResolverError) as e:
|
|
56
73
|
console.print(f"[red]Error loading config: {e}[/]")
|
|
57
74
|
ctx.exit(1)
|
|
75
|
+
finally:
|
|
76
|
+
# Clean up: remove the cwd from sys.path if we added it
|
|
77
|
+
if cwd_added and cwd in sys.path and sys.path[0] == cwd:
|
|
78
|
+
sys.path.remove(cwd)
|
|
58
79
|
|
|
59
80
|
return sqlspec_group
|
|
60
81
|
|
|
61
82
|
|
|
62
|
-
def add_migration_commands(database_group:
|
|
83
|
+
def add_migration_commands(database_group: "Group | None" = None) -> "Group":
|
|
63
84
|
"""Add migration commands to the database group.
|
|
64
85
|
|
|
65
86
|
Args:
|
|
66
87
|
database_group: The database group to add the commands to.
|
|
67
88
|
|
|
68
|
-
Raises:
|
|
69
|
-
MissingDependencyError: If the `click` package is not installed.
|
|
70
|
-
|
|
71
89
|
Returns:
|
|
72
90
|
The database group with the migration commands added.
|
|
73
91
|
"""
|
|
74
|
-
from sqlspec.exceptions import MissingDependencyError
|
|
75
|
-
|
|
76
|
-
try:
|
|
77
|
-
import rich_click as click
|
|
78
|
-
except ImportError:
|
|
79
|
-
try:
|
|
80
|
-
import click # type: ignore[no-redef]
|
|
81
|
-
except ImportError as e:
|
|
82
|
-
raise MissingDependencyError(package="click", install_package="cli") from e
|
|
83
92
|
from rich import get_console
|
|
84
93
|
|
|
85
94
|
console = get_console()
|
|
@@ -109,10 +118,22 @@ def add_migration_commands(database_group: Optional["Group"] = None) -> "Group":
|
|
|
109
118
|
dry_run_option = click.option(
|
|
110
119
|
"--dry-run", is_flag=True, default=False, help="Show what would be executed without making changes"
|
|
111
120
|
)
|
|
121
|
+
execution_mode_option = click.option(
|
|
122
|
+
"--execution-mode",
|
|
123
|
+
type=click.Choice(["auto", "sync", "async"]),
|
|
124
|
+
default="auto",
|
|
125
|
+
help="Force execution mode (auto-detects by default)",
|
|
126
|
+
)
|
|
127
|
+
no_auto_sync_option = click.option(
|
|
128
|
+
"--no-auto-sync",
|
|
129
|
+
is_flag=True,
|
|
130
|
+
default=False,
|
|
131
|
+
help="Disable automatic version reconciliation when migrations have been renamed",
|
|
132
|
+
)
|
|
112
133
|
|
|
113
134
|
def get_config_by_bind_key(
|
|
114
|
-
ctx: "click.Context", bind_key:
|
|
115
|
-
) -> "
|
|
135
|
+
ctx: "click.Context", bind_key: str | None
|
|
136
|
+
) -> "AsyncDatabaseConfig[Any, Any, Any] | SyncDatabaseConfig[Any, Any, Any]":
|
|
116
137
|
"""Get the SQLSpec config for the specified bind key.
|
|
117
138
|
|
|
118
139
|
Args:
|
|
@@ -128,7 +149,7 @@ def add_migration_commands(database_group: Optional["Group"] = None) -> "Group":
|
|
|
128
149
|
else:
|
|
129
150
|
config = None
|
|
130
151
|
for cfg in configs:
|
|
131
|
-
config_name =
|
|
152
|
+
config_name = cfg.bind_key
|
|
132
153
|
if config_name == bind_key:
|
|
133
154
|
config = cfg
|
|
134
155
|
break
|
|
@@ -137,13 +158,7 @@ def add_migration_commands(database_group: Optional["Group"] = None) -> "Group":
|
|
|
137
158
|
console.print(f"[red]No config found for bind key: {bind_key}[/]")
|
|
138
159
|
sys.exit(1)
|
|
139
160
|
|
|
140
|
-
|
|
141
|
-
from sqlspec.extensions.litestar.config import DatabaseConfig
|
|
142
|
-
|
|
143
|
-
if isinstance(config, DatabaseConfig):
|
|
144
|
-
config = config.config
|
|
145
|
-
|
|
146
|
-
return cast("Union[AsyncDatabaseConfig[Any, Any, Any], SyncDatabaseConfig[Any, Any, Any]]", config)
|
|
161
|
+
return cast("AsyncDatabaseConfig[Any, Any, Any] | SyncDatabaseConfig[Any, Any, Any]", config)
|
|
147
162
|
|
|
148
163
|
def get_configs_with_migrations(ctx: "click.Context", enabled_only: bool = False) -> "list[tuple[str, Any]]":
|
|
149
164
|
"""Get all configurations that have migrations enabled.
|
|
@@ -158,22 +173,13 @@ def add_migration_commands(database_group: Optional["Group"] = None) -> "Group":
|
|
|
158
173
|
configs = ctx.obj["configs"]
|
|
159
174
|
migration_configs = []
|
|
160
175
|
|
|
161
|
-
from sqlspec.extensions.litestar.config import DatabaseConfig
|
|
162
|
-
|
|
163
176
|
for config in configs:
|
|
164
|
-
|
|
165
|
-
actual_config = config.config if isinstance(config, DatabaseConfig) else config
|
|
166
|
-
|
|
167
|
-
migration_config = getattr(actual_config, "migration_config", None)
|
|
177
|
+
migration_config = config.migration_config
|
|
168
178
|
if migration_config:
|
|
169
179
|
enabled = migration_config.get("enabled", True)
|
|
170
180
|
if not enabled_only or enabled:
|
|
171
|
-
config_name = (
|
|
172
|
-
|
|
173
|
-
or getattr(actual_config, "bind_key", None)
|
|
174
|
-
or str(type(actual_config).__name__)
|
|
175
|
-
)
|
|
176
|
-
migration_configs.append((config_name, actual_config))
|
|
181
|
+
config_name = config.bind_key or str(type(config).__name__)
|
|
182
|
+
migration_configs.append((config_name, config))
|
|
177
183
|
|
|
178
184
|
return migration_configs
|
|
179
185
|
|
|
@@ -197,14 +203,20 @@ def add_migration_commands(database_group: Optional["Group"] = None) -> "Group":
|
|
|
197
203
|
filtered = [(name, config) for name, config in filtered if name not in exclude]
|
|
198
204
|
return filtered
|
|
199
205
|
|
|
206
|
+
async def maybe_await(result: Any) -> Any:
|
|
207
|
+
"""Await result if it's a coroutine, otherwise return it directly."""
|
|
208
|
+
if inspect.iscoroutine(result):
|
|
209
|
+
return await result
|
|
210
|
+
return result
|
|
211
|
+
|
|
200
212
|
def process_multiple_configs(
|
|
201
213
|
ctx: "click.Context",
|
|
202
|
-
bind_key:
|
|
214
|
+
bind_key: str | None,
|
|
203
215
|
include: "tuple[str, ...]",
|
|
204
216
|
exclude: "tuple[str, ...]",
|
|
205
217
|
dry_run: bool,
|
|
206
218
|
operation_name: str,
|
|
207
|
-
) -> "
|
|
219
|
+
) -> "list[tuple[str, Any]] | None":
|
|
208
220
|
"""Process configuration selection for multi-config operations.
|
|
209
221
|
|
|
210
222
|
Args:
|
|
@@ -252,37 +264,47 @@ def add_migration_commands(database_group: Optional["Group"] = None) -> "Group":
|
|
|
252
264
|
@include_option
|
|
253
265
|
@exclude_option
|
|
254
266
|
def show_database_revision( # pyright: ignore[reportUnusedFunction]
|
|
255
|
-
bind_key:
|
|
267
|
+
bind_key: str | None, verbose: bool, include: "tuple[str, ...]", exclude: "tuple[str, ...]"
|
|
256
268
|
) -> None:
|
|
257
269
|
"""Show current database revision."""
|
|
258
|
-
from sqlspec.migrations.commands import
|
|
270
|
+
from sqlspec.migrations.commands import create_migration_commands
|
|
271
|
+
from sqlspec.utils.sync_tools import run_
|
|
259
272
|
|
|
260
273
|
ctx = click.get_current_context()
|
|
261
274
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
275
|
+
async def _show_current_revision() -> None:
|
|
276
|
+
# Check if this is a multi-config operation
|
|
277
|
+
configs_to_process = process_multiple_configs(
|
|
278
|
+
cast("click.Context", ctx),
|
|
279
|
+
bind_key,
|
|
280
|
+
include,
|
|
281
|
+
exclude,
|
|
282
|
+
dry_run=False,
|
|
283
|
+
operation_name="show current revision",
|
|
284
|
+
)
|
|
270
285
|
|
|
271
|
-
|
|
286
|
+
if configs_to_process is not None:
|
|
287
|
+
if not configs_to_process:
|
|
288
|
+
return
|
|
289
|
+
|
|
290
|
+
console.rule("[yellow]Listing current revisions for all configurations[/]", align="left")
|
|
291
|
+
|
|
292
|
+
for config_name, config in configs_to_process:
|
|
293
|
+
console.print(f"\n[blue]Configuration: {config_name}[/]")
|
|
294
|
+
try:
|
|
295
|
+
migration_commands: SyncMigrationCommands[Any] | AsyncMigrationCommands[Any] = (
|
|
296
|
+
create_migration_commands(config=config)
|
|
297
|
+
)
|
|
298
|
+
await maybe_await(migration_commands.current(verbose=verbose))
|
|
299
|
+
except Exception as e:
|
|
300
|
+
console.print(f"[red]✗ Failed to get current revision for {config_name}: {e}[/]")
|
|
301
|
+
else:
|
|
302
|
+
console.rule("[yellow]Listing current revision[/]", align="left")
|
|
303
|
+
sqlspec_config = get_config_by_bind_key(cast("click.Context", ctx), bind_key)
|
|
304
|
+
migration_commands = create_migration_commands(config=sqlspec_config)
|
|
305
|
+
await maybe_await(migration_commands.current(verbose=verbose))
|
|
272
306
|
|
|
273
|
-
|
|
274
|
-
console.print(f"\n[blue]Configuration: {config_name}[/]")
|
|
275
|
-
try:
|
|
276
|
-
migration_commands = MigrationCommands(config=config)
|
|
277
|
-
migration_commands.current(verbose=verbose)
|
|
278
|
-
except Exception as e:
|
|
279
|
-
console.print(f"[red]✗ Failed to get current revision for {config_name}: {e}[/]")
|
|
280
|
-
else:
|
|
281
|
-
# Single config operation
|
|
282
|
-
console.rule("[yellow]Listing current revision[/]", align="left")
|
|
283
|
-
sqlspec_config = get_config_by_bind_key(ctx, bind_key)
|
|
284
|
-
migration_commands = MigrationCommands(config=sqlspec_config)
|
|
285
|
-
migration_commands.current(verbose=verbose)
|
|
307
|
+
run_(_show_current_revision)()
|
|
286
308
|
|
|
287
309
|
@database_group.command(name="downgrade", help="Downgrade database to a specific revision.")
|
|
288
310
|
@bind_key_option
|
|
@@ -292,7 +314,7 @@ def add_migration_commands(database_group: Optional["Group"] = None) -> "Group":
|
|
|
292
314
|
@dry_run_option
|
|
293
315
|
@click.argument("revision", type=str, default="-1")
|
|
294
316
|
def downgrade_database( # pyright: ignore[reportUnusedFunction]
|
|
295
|
-
bind_key:
|
|
317
|
+
bind_key: str | None,
|
|
296
318
|
revision: str,
|
|
297
319
|
no_prompt: bool,
|
|
298
320
|
include: "tuple[str, ...]",
|
|
@@ -302,47 +324,58 @@ def add_migration_commands(database_group: Optional["Group"] = None) -> "Group":
|
|
|
302
324
|
"""Downgrade the database to the latest revision."""
|
|
303
325
|
from rich.prompt import Confirm
|
|
304
326
|
|
|
305
|
-
from sqlspec.migrations.commands import
|
|
327
|
+
from sqlspec.migrations.commands import create_migration_commands
|
|
328
|
+
from sqlspec.utils.sync_tools import run_
|
|
306
329
|
|
|
307
330
|
ctx = click.get_current_context()
|
|
308
331
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
if not no_prompt and not Confirm.ask(
|
|
319
|
-
f"[bold]Are you sure you want to downgrade {len(configs_to_process)} configuration(s) to revision {revision}?[/]"
|
|
320
|
-
):
|
|
321
|
-
console.print("[yellow]Operation cancelled.[/]")
|
|
322
|
-
return
|
|
323
|
-
|
|
324
|
-
console.rule("[yellow]Starting multi-configuration downgrade process[/]", align="left")
|
|
325
|
-
|
|
326
|
-
for config_name, config in configs_to_process:
|
|
327
|
-
console.print(f"[blue]Downgrading configuration: {config_name}[/]")
|
|
328
|
-
try:
|
|
329
|
-
migration_commands = MigrationCommands(config=config)
|
|
330
|
-
migration_commands.downgrade(revision=revision)
|
|
331
|
-
console.print(f"[green]✓ Successfully downgraded: {config_name}[/]")
|
|
332
|
-
except Exception as e:
|
|
333
|
-
console.print(f"[red]✗ Failed to downgrade {config_name}: {e}[/]")
|
|
334
|
-
else:
|
|
335
|
-
# Single config operation
|
|
336
|
-
console.rule("[yellow]Starting database downgrade process[/]", align="left")
|
|
337
|
-
input_confirmed = (
|
|
338
|
-
True
|
|
339
|
-
if no_prompt
|
|
340
|
-
else Confirm.ask(f"Are you sure you want to downgrade the database to the `{revision}` revision?")
|
|
332
|
+
async def _downgrade_database() -> None:
|
|
333
|
+
# Check if this is a multi-config operation
|
|
334
|
+
configs_to_process = process_multiple_configs(
|
|
335
|
+
cast("click.Context", ctx),
|
|
336
|
+
bind_key,
|
|
337
|
+
include,
|
|
338
|
+
exclude,
|
|
339
|
+
dry_run=dry_run,
|
|
340
|
+
operation_name=f"downgrade to {revision}",
|
|
341
341
|
)
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
342
|
+
|
|
343
|
+
if configs_to_process is not None:
|
|
344
|
+
if not configs_to_process:
|
|
345
|
+
return
|
|
346
|
+
|
|
347
|
+
if not no_prompt and not Confirm.ask(
|
|
348
|
+
f"[bold]Are you sure you want to downgrade {len(configs_to_process)} configuration(s) to revision {revision}?[/]"
|
|
349
|
+
):
|
|
350
|
+
console.print("[yellow]Operation cancelled.[/]")
|
|
351
|
+
return
|
|
352
|
+
|
|
353
|
+
console.rule("[yellow]Starting multi-configuration downgrade process[/]", align="left")
|
|
354
|
+
|
|
355
|
+
for config_name, config in configs_to_process:
|
|
356
|
+
console.print(f"[blue]Downgrading configuration: {config_name}[/]")
|
|
357
|
+
try:
|
|
358
|
+
migration_commands: SyncMigrationCommands[Any] | AsyncMigrationCommands[Any] = (
|
|
359
|
+
create_migration_commands(config=config)
|
|
360
|
+
)
|
|
361
|
+
await maybe_await(migration_commands.downgrade(revision=revision, dry_run=dry_run))
|
|
362
|
+
console.print(f"[green]✓ Successfully downgraded: {config_name}[/]")
|
|
363
|
+
except Exception as e:
|
|
364
|
+
console.print(f"[red]✗ Failed to downgrade {config_name}: {e}[/]")
|
|
365
|
+
else:
|
|
366
|
+
# Single config operation
|
|
367
|
+
console.rule("[yellow]Starting database downgrade process[/]", align="left")
|
|
368
|
+
input_confirmed = (
|
|
369
|
+
True
|
|
370
|
+
if no_prompt
|
|
371
|
+
else Confirm.ask(f"Are you sure you want to downgrade the database to the `{revision}` revision?")
|
|
372
|
+
)
|
|
373
|
+
if input_confirmed:
|
|
374
|
+
sqlspec_config = get_config_by_bind_key(cast("click.Context", ctx), bind_key)
|
|
375
|
+
migration_commands = create_migration_commands(config=sqlspec_config)
|
|
376
|
+
await maybe_await(migration_commands.downgrade(revision=revision, dry_run=dry_run))
|
|
377
|
+
|
|
378
|
+
run_(_downgrade_database)()
|
|
346
379
|
|
|
347
380
|
@database_group.command(name="upgrade", help="Upgrade database to a specific revision.")
|
|
348
381
|
@bind_key_option
|
|
@@ -350,71 +383,96 @@ def add_migration_commands(database_group: Optional["Group"] = None) -> "Group":
|
|
|
350
383
|
@include_option
|
|
351
384
|
@exclude_option
|
|
352
385
|
@dry_run_option
|
|
386
|
+
@execution_mode_option
|
|
387
|
+
@no_auto_sync_option
|
|
353
388
|
@click.argument("revision", type=str, default="head")
|
|
354
389
|
def upgrade_database( # pyright: ignore[reportUnusedFunction]
|
|
355
|
-
bind_key:
|
|
390
|
+
bind_key: str | None,
|
|
356
391
|
revision: str,
|
|
357
392
|
no_prompt: bool,
|
|
358
393
|
include: "tuple[str, ...]",
|
|
359
394
|
exclude: "tuple[str, ...]",
|
|
360
395
|
dry_run: bool,
|
|
396
|
+
execution_mode: str,
|
|
397
|
+
no_auto_sync: bool,
|
|
361
398
|
) -> None:
|
|
362
399
|
"""Upgrade the database to the latest revision."""
|
|
363
400
|
from rich.prompt import Confirm
|
|
364
401
|
|
|
365
|
-
from sqlspec.migrations.commands import
|
|
402
|
+
from sqlspec.migrations.commands import create_migration_commands
|
|
403
|
+
from sqlspec.utils.sync_tools import run_
|
|
366
404
|
|
|
367
405
|
ctx = click.get_current_context()
|
|
368
406
|
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
if not no_prompt and not Confirm.ask(
|
|
379
|
-
f"[bold]Are you sure you want to upgrade {len(configs_to_process)} configuration(s) to revision {revision}?[/]"
|
|
380
|
-
):
|
|
381
|
-
console.print("[yellow]Operation cancelled.[/]")
|
|
382
|
-
return
|
|
383
|
-
|
|
384
|
-
console.rule("[yellow]Starting multi-configuration upgrade process[/]", align="left")
|
|
385
|
-
|
|
386
|
-
for config_name, config in configs_to_process:
|
|
387
|
-
console.print(f"[blue]Upgrading configuration: {config_name}[/]")
|
|
388
|
-
try:
|
|
389
|
-
migration_commands = MigrationCommands(config=config)
|
|
390
|
-
migration_commands.upgrade(revision=revision)
|
|
391
|
-
console.print(f"[green]✓ Successfully upgraded: {config_name}[/]")
|
|
392
|
-
except Exception as e:
|
|
393
|
-
console.print(f"[red]✗ Failed to upgrade {config_name}: {e}[/]")
|
|
394
|
-
else:
|
|
395
|
-
# Single config operation
|
|
396
|
-
console.rule("[yellow]Starting database upgrade process[/]", align="left")
|
|
397
|
-
input_confirmed = (
|
|
398
|
-
True
|
|
399
|
-
if no_prompt
|
|
400
|
-
else Confirm.ask(f"[bold]Are you sure you want migrate the database to the `{revision}` revision?[/]")
|
|
407
|
+
async def _upgrade_database() -> None:
|
|
408
|
+
# Report execution mode when specified
|
|
409
|
+
if execution_mode != "auto":
|
|
410
|
+
console.print(f"[dim]Execution mode: {execution_mode}[/]")
|
|
411
|
+
|
|
412
|
+
# Check if this is a multi-config operation
|
|
413
|
+
configs_to_process = process_multiple_configs(
|
|
414
|
+
cast("click.Context", ctx), bind_key, include, exclude, dry_run, operation_name=f"upgrade to {revision}"
|
|
401
415
|
)
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
416
|
+
|
|
417
|
+
if configs_to_process is not None:
|
|
418
|
+
if not configs_to_process:
|
|
419
|
+
return
|
|
420
|
+
|
|
421
|
+
if not no_prompt and not Confirm.ask(
|
|
422
|
+
f"[bold]Are you sure you want to upgrade {len(configs_to_process)} configuration(s) to revision {revision}?[/]"
|
|
423
|
+
):
|
|
424
|
+
console.print("[yellow]Operation cancelled.[/]")
|
|
425
|
+
return
|
|
426
|
+
|
|
427
|
+
console.rule("[yellow]Starting multi-configuration upgrade process[/]", align="left")
|
|
428
|
+
|
|
429
|
+
for config_name, config in configs_to_process:
|
|
430
|
+
console.print(f"[blue]Upgrading configuration: {config_name}[/]")
|
|
431
|
+
try:
|
|
432
|
+
migration_commands: SyncMigrationCommands[Any] | AsyncMigrationCommands[Any] = (
|
|
433
|
+
create_migration_commands(config=config)
|
|
434
|
+
)
|
|
435
|
+
await maybe_await(
|
|
436
|
+
migration_commands.upgrade(revision=revision, auto_sync=not no_auto_sync, dry_run=dry_run)
|
|
437
|
+
)
|
|
438
|
+
console.print(f"[green]✓ Successfully upgraded: {config_name}[/]")
|
|
439
|
+
except Exception as e:
|
|
440
|
+
console.print(f"[red]✗ Failed to upgrade {config_name}: {e}[/]")
|
|
441
|
+
else:
|
|
442
|
+
# Single config operation
|
|
443
|
+
console.rule("[yellow]Starting database upgrade process[/]", align="left")
|
|
444
|
+
input_confirmed = (
|
|
445
|
+
True
|
|
446
|
+
if no_prompt
|
|
447
|
+
else Confirm.ask(
|
|
448
|
+
f"[bold]Are you sure you want migrate the database to the `{revision}` revision?[/]"
|
|
449
|
+
)
|
|
450
|
+
)
|
|
451
|
+
if input_confirmed:
|
|
452
|
+
sqlspec_config = get_config_by_bind_key(cast("click.Context", ctx), bind_key)
|
|
453
|
+
migration_commands = create_migration_commands(config=sqlspec_config)
|
|
454
|
+
await maybe_await(
|
|
455
|
+
migration_commands.upgrade(revision=revision, auto_sync=not no_auto_sync, dry_run=dry_run)
|
|
456
|
+
)
|
|
457
|
+
|
|
458
|
+
run_(_upgrade_database)()
|
|
406
459
|
|
|
407
460
|
@database_group.command(help="Stamp the revision table with the given revision")
|
|
408
461
|
@click.argument("revision", type=str)
|
|
409
462
|
@bind_key_option
|
|
410
|
-
def stamp(bind_key:
|
|
463
|
+
def stamp(bind_key: str | None, revision: str) -> None: # pyright: ignore[reportUnusedFunction]
|
|
411
464
|
"""Stamp the revision table with the given revision."""
|
|
412
|
-
from sqlspec.migrations.commands import
|
|
465
|
+
from sqlspec.migrations.commands import create_migration_commands
|
|
466
|
+
from sqlspec.utils.sync_tools import run_
|
|
413
467
|
|
|
414
468
|
ctx = click.get_current_context()
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
469
|
+
|
|
470
|
+
async def _stamp() -> None:
|
|
471
|
+
sqlspec_config = get_config_by_bind_key(cast("click.Context", ctx), bind_key)
|
|
472
|
+
migration_commands = create_migration_commands(config=sqlspec_config)
|
|
473
|
+
await maybe_await(migration_commands.stamp(revision=revision))
|
|
474
|
+
|
|
475
|
+
run_(_stamp)()
|
|
418
476
|
|
|
419
477
|
@database_group.command(name="init", help="Initialize migrations for the project.")
|
|
420
478
|
@bind_key_option
|
|
@@ -422,58 +480,113 @@ def add_migration_commands(database_group: Optional["Group"] = None) -> "Group":
|
|
|
422
480
|
@click.option("--package", is_flag=True, default=True, help="Create `__init__.py` for created folder")
|
|
423
481
|
@no_prompt_option
|
|
424
482
|
def init_sqlspec( # pyright: ignore[reportUnusedFunction]
|
|
425
|
-
bind_key:
|
|
483
|
+
bind_key: str | None, directory: str | None, package: bool, no_prompt: bool
|
|
426
484
|
) -> None:
|
|
427
485
|
"""Initialize the database migrations."""
|
|
428
486
|
from rich.prompt import Confirm
|
|
429
487
|
|
|
430
|
-
from sqlspec.migrations.commands import
|
|
488
|
+
from sqlspec.migrations.commands import create_migration_commands
|
|
489
|
+
from sqlspec.utils.sync_tools import run_
|
|
431
490
|
|
|
432
491
|
ctx = click.get_current_context()
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
492
|
+
|
|
493
|
+
async def _init_sqlspec() -> None:
|
|
494
|
+
console.rule("[yellow]Initializing database migrations.", align="left")
|
|
495
|
+
input_confirmed = (
|
|
496
|
+
True
|
|
497
|
+
if no_prompt
|
|
498
|
+
else Confirm.ask("[bold]Are you sure you want initialize migrations for the project?[/]")
|
|
499
|
+
)
|
|
500
|
+
if input_confirmed:
|
|
501
|
+
configs = (
|
|
502
|
+
[get_config_by_bind_key(cast("click.Context", ctx), bind_key)]
|
|
503
|
+
if bind_key is not None
|
|
504
|
+
else cast("click.Context", ctx).obj["configs"]
|
|
505
|
+
)
|
|
506
|
+
|
|
507
|
+
for config in configs:
|
|
508
|
+
migration_config = getattr(config, "migration_config", {})
|
|
509
|
+
target_directory = (
|
|
510
|
+
str(migration_config.get("script_location", "migrations")) if directory is None else directory
|
|
511
|
+
)
|
|
512
|
+
migration_commands = create_migration_commands(config=config)
|
|
513
|
+
await maybe_await(migration_commands.init(directory=target_directory, package=package))
|
|
514
|
+
|
|
515
|
+
run_(_init_sqlspec)()
|
|
516
|
+
|
|
517
|
+
@database_group.command(
|
|
518
|
+
name="create-migration", aliases=["make-migration"], help="Create a new migration revision."
|
|
519
|
+
)
|
|
450
520
|
@bind_key_option
|
|
451
521
|
@click.option("-m", "--message", default=None, help="Revision message")
|
|
452
522
|
@no_prompt_option
|
|
453
523
|
def create_revision( # pyright: ignore[reportUnusedFunction]
|
|
454
|
-
bind_key:
|
|
524
|
+
bind_key: str | None, message: str | None, no_prompt: bool
|
|
455
525
|
) -> None:
|
|
456
526
|
"""Create a new database revision."""
|
|
457
527
|
from rich.prompt import Prompt
|
|
458
528
|
|
|
459
|
-
from sqlspec.migrations.commands import
|
|
529
|
+
from sqlspec.migrations.commands import create_migration_commands
|
|
530
|
+
from sqlspec.utils.sync_tools import run_
|
|
460
531
|
|
|
461
532
|
ctx = click.get_current_context()
|
|
462
|
-
console.rule("[yellow]Creating new migration revision[/]", align="left")
|
|
463
|
-
if message is None:
|
|
464
|
-
message = "new migration" if no_prompt else Prompt.ask("Please enter a message describing this revision")
|
|
465
533
|
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
534
|
+
async def _create_revision() -> None:
|
|
535
|
+
console.rule("[yellow]Creating new migration revision[/]", align="left")
|
|
536
|
+
message_text = message
|
|
537
|
+
if message_text is None:
|
|
538
|
+
message_text = (
|
|
539
|
+
"new migration" if no_prompt else Prompt.ask("Please enter a message describing this revision")
|
|
540
|
+
)
|
|
541
|
+
|
|
542
|
+
sqlspec_config = get_config_by_bind_key(cast("click.Context", ctx), bind_key)
|
|
543
|
+
migration_commands = create_migration_commands(config=sqlspec_config)
|
|
544
|
+
await maybe_await(migration_commands.revision(message=message_text))
|
|
545
|
+
|
|
546
|
+
run_(_create_revision)()
|
|
547
|
+
|
|
548
|
+
@database_group.command(name="fix", help="Convert timestamp migrations to sequential format.")
|
|
549
|
+
@bind_key_option
|
|
550
|
+
@dry_run_option
|
|
551
|
+
@click.option("--yes", is_flag=True, help="Skip confirmation prompt")
|
|
552
|
+
@click.option("--no-database", is_flag=True, help="Skip database record updates")
|
|
553
|
+
def fix_migrations( # pyright: ignore[reportUnusedFunction]
|
|
554
|
+
bind_key: str | None, dry_run: bool, yes: bool, no_database: bool
|
|
555
|
+
) -> None:
|
|
556
|
+
"""Convert timestamp migrations to sequential format."""
|
|
557
|
+
from sqlspec.migrations.commands import create_migration_commands
|
|
558
|
+
from sqlspec.utils.sync_tools import run_
|
|
559
|
+
|
|
560
|
+
ctx = click.get_current_context()
|
|
561
|
+
|
|
562
|
+
async def _fix_migrations() -> None:
|
|
563
|
+
console.rule("[yellow]Migration Fix Command[/]", align="left")
|
|
564
|
+
sqlspec_config = get_config_by_bind_key(cast("click.Context", ctx), bind_key)
|
|
565
|
+
migration_commands = create_migration_commands(config=sqlspec_config)
|
|
566
|
+
await maybe_await(migration_commands.fix(dry_run=dry_run, update_database=not no_database, yes=yes))
|
|
567
|
+
|
|
568
|
+
run_(_fix_migrations)()
|
|
469
569
|
|
|
470
570
|
@database_group.command(name="show-config", help="Show all configurations with migrations enabled.")
|
|
471
|
-
|
|
571
|
+
@bind_key_option
|
|
572
|
+
def show_config(bind_key: str | None = None) -> None: # pyright: ignore[reportUnusedFunction]
|
|
472
573
|
"""Show and display all configurations with migrations enabled."""
|
|
473
574
|
from rich.table import Table
|
|
474
575
|
|
|
475
576
|
ctx = click.get_current_context()
|
|
476
|
-
|
|
577
|
+
|
|
578
|
+
# If bind_key is provided, filter to only that config
|
|
579
|
+
if bind_key is not None:
|
|
580
|
+
get_config_by_bind_key(cast("click.Context", ctx), bind_key)
|
|
581
|
+
# Convert single config to list format for compatibility
|
|
582
|
+
all_configs = cast("click.Context", ctx).obj["configs"]
|
|
583
|
+
migration_configs = []
|
|
584
|
+
for cfg in all_configs:
|
|
585
|
+
config_name = cfg.bind_key
|
|
586
|
+
if config_name == bind_key and hasattr(cfg, "migration_config") and cfg.migration_config:
|
|
587
|
+
migration_configs.append((config_name, cfg))
|
|
588
|
+
else:
|
|
589
|
+
migration_configs = get_configs_with_migrations(cast("click.Context", ctx))
|
|
477
590
|
|
|
478
591
|
if not migration_configs:
|
|
479
592
|
console.print("[yellow]No configurations with migrations detected.[/]")
|
|
@@ -487,7 +600,7 @@ def add_migration_commands(database_group: Optional["Group"] = None) -> "Group":
|
|
|
487
600
|
for config_name, config in migration_configs:
|
|
488
601
|
migration_config = getattr(config, "migration_config", {})
|
|
489
602
|
script_location = migration_config.get("script_location", "migrations")
|
|
490
|
-
table.add_row(config_name, script_location, "Migration Enabled")
|
|
603
|
+
table.add_row(config_name, str(script_location), "Migration Enabled")
|
|
491
604
|
|
|
492
605
|
console.print(table)
|
|
493
606
|
console.print(f"[blue]Found {len(migration_configs)} configuration(s) with migrations enabled.[/]")
|