|
31 | 31 | # Helpers
|
32 | 32 | # ──────────────────────────────────────────────────────────────────────────────
|
33 | 33 | def _use_batch() -> bool:
|
| 34 | + """Determine if batch operations are required for the current database. |
| 35 | +
|
| 36 | + SQLite requires batch mode for certain ALTER TABLE operations like dropping |
| 37 | + columns or altering column types. This helper checks the database dialect |
| 38 | + to determine if batch operations should be used. |
| 39 | +
|
| 40 | + Returns: |
| 41 | + bool: True if the database is SQLite (requires batch mode), False otherwise. |
| 42 | +
|
| 43 | + Examples: |
| 44 | + >>> # In a SQLite context |
| 45 | + >>> _use_batch() # doctest: +SKIP |
| 46 | + True |
| 47 | + >>> # In a PostgreSQL context |
| 48 | + >>> _use_batch() # doctest: +SKIP |
| 49 | + False |
| 50 | + """ |
34 | 51 | return op.get_bind().dialect.name == "sqlite"
|
35 | 52 |
|
36 | 53 |
|
37 | 54 | # ──────────────────────────────────────────────────────────────────────────────
|
38 | 55 | # Upgrade
|
39 | 56 | # ──────────────────────────────────────────────────────────────────────────────
|
40 | 57 | def upgrade() -> None:
|
| 58 | + """Migrate database schema from integer to UUID primary keys with slugs. |
| 59 | +
|
| 60 | + This migration performs a comprehensive schema transformation in three stages: |
| 61 | +
|
| 62 | + Stage 1 - Add placeholder columns: |
| 63 | + - Adds UUID columns (id_new) to gateways, tools, and servers |
| 64 | + - Adds slug columns for human-readable identifiers |
| 65 | + - Adds columns to preserve original tool names before prefixing |
| 66 | +
|
| 67 | + Stage 2 - Data migration: |
| 68 | + - Generates UUIDs for all primary keys |
| 69 | + - Creates slugs from names (e.g., "My Gateway" -> "my-gateway") |
| 70 | + - Prefixes tool names with gateway slugs (e.g., "my-tool" -> "gateway-slug-my-tool") |
| 71 | + - Updates all foreign key references to use new UUIDs |
| 72 | +
|
| 73 | + Stage 3 - Schema finalization: |
| 74 | + - Drops old integer columns |
| 75 | + - Renames new UUID columns to replace old ones |
| 76 | + - Recreates primary keys and foreign key constraints |
| 77 | + - Adds unique constraints on slugs and URLs |
| 78 | +
|
| 79 | + The migration is designed to work with both SQLite (using batch operations) |
| 80 | + and other databases. It preserves all existing data relationships while |
| 81 | + transforming the schema. |
| 82 | +
|
| 83 | + Note: |
| 84 | + - Skips migration if database is fresh (no gateways table) |
| 85 | + - Uses batch operations for SQLite compatibility |
| 86 | + - Commits data changes before schema alterations |
| 87 | +
|
| 88 | + Examples: |
| 89 | + >>> # Running the migration |
| 90 | + >>> upgrade() # doctest: +SKIP |
| 91 | + Fresh database detected. Skipping migration. |
| 92 | + >>> # Or for existing database |
| 93 | + >>> upgrade() # doctest: +SKIP |
| 94 | + Existing installation detected. Starting data and schema migration... |
| 95 | + """ |
41 | 96 | bind = op.get_bind()
|
42 | 97 | sess = Session(bind=bind)
|
43 | 98 | inspector = sa.inspect(bind)
|
@@ -402,6 +457,39 @@ def upgrade() -> None:
|
402 | 457 |
|
403 | 458 |
|
404 | 459 | def downgrade() -> None:
|
| 460 | + """Revert database schema from UUID primary keys back to integers. |
| 461 | +
|
| 462 | + This downgrade reverses the UUID migration but with significant limitations: |
| 463 | + - Schema structure is restored but data is NOT preserved |
| 464 | + - All UUID values and slug fields are lost |
| 465 | + - Foreign key relationships are broken (columns will be NULL) |
| 466 | + - Original integer IDs cannot be recovered |
| 467 | +
|
| 468 | + The downgrade operates in reverse order of the upgrade: |
| 469 | +
|
| 470 | + Stage 1 - Revert schema changes: |
| 471 | + - Drops UUID-based constraints and keys |
| 472 | + - Renames UUID columns back to temporary names |
| 473 | + - Re-adds integer columns (empty/NULL) |
| 474 | +
|
| 475 | + Stage 2 - Data migration (skipped): |
| 476 | + - Original integer IDs cannot be restored from UUIDs |
| 477 | + - Relationships cannot be reconstructed |
| 478 | +
|
| 479 | + Stage 3 - Remove temporary columns: |
| 480 | + - Drops all UUID and slug columns |
| 481 | + - Leaves database with original schema but no data |
| 482 | +
|
| 483 | + Warning: |
| 484 | + This downgrade is destructive and should only be used if you need |
| 485 | + to revert the schema structure. All data in affected tables will |
| 486 | + need to be manually restored from backups. |
| 487 | +
|
| 488 | + Examples: |
| 489 | + >>> # Running the downgrade |
| 490 | + >>> downgrade() # doctest: +SKIP |
| 491 | + # Schema reverted but data is lost |
| 492 | + """ |
405 | 493 | # ── STAGE 1 (REVERSE): Revert Schema to original state ─────────────────
|
406 | 494 | # This reverses the operations from STAGE 3 of the upgrade.
|
407 | 495 | # Data from the new columns will be lost, which is expected.
|
|
0 commit comments