3fa376905c
Implements Alembic for managing token storage database schema versions. Migrations run automatically on startup with full backward compatibility. **Changes:** - Add Alembic dependency (1.14.0+) and SQLAlchemy (auto-installed) - Create migration infrastructure in alembic/ directory - Add initial migration (001) capturing current schema - Modify RefreshTokenStorage.initialize() to run migrations via anyio - Add CLI commands: db upgrade, current, history, downgrade, migrate - Add comprehensive migration documentation **Backward Compatibility:** - Pre-Alembic databases automatically stamped with revision 001 - No schema changes for existing databases - Automatic upgrade on first startup after update **Migration Strategy:** Three scenarios handled: 1. New database → Run migrations from scratch 2. Pre-Alembic database → Stamp with 001 (no changes) 3. Alembic-managed → Upgrade to latest **Architecture:** - Uses anyio.to_thread.run_sync() for structured concurrency - Alembic env.py runs with anyio.run() in worker thread - SQLite-friendly migration patterns documented - No ThreadPoolExecutor needed (anyio handles it) **CLI Usage:** ```bash nextcloud-mcp-server db upgrade # Upgrade to latest nextcloud-mcp-server db current # Show version nextcloud-mcp-server db history # View changelog nextcloud-mcp-server db downgrade # Rollback (with confirmation) nextcloud-mcp-server db migrate "description" # Create migration ``` **Testing:** - All 13 webhook storage tests pass - New/pre-Alembic database scenarios validated - anyio integration tested 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
72 lines
2.2 KiB
Plaintext
72 lines
2.2 KiB
Plaintext
Database Migrations for nextcloud-mcp-server
|
|
============================================
|
|
|
|
This directory contains Alembic database migrations for the token storage database.
|
|
|
|
Structure
|
|
---------
|
|
- env.py: Alembic environment configuration
|
|
- script.py.mako: Template for generating new migration files
|
|
- versions/: Directory containing migration scripts
|
|
|
|
Usage
|
|
-----
|
|
Migrations are managed via the CLI:
|
|
|
|
# Upgrade database to latest version
|
|
uv run nextcloud-mcp-server db upgrade
|
|
|
|
# Show current database version
|
|
uv run nextcloud-mcp-server db current
|
|
|
|
# Show migration history
|
|
uv run nextcloud-mcp-server db history
|
|
|
|
# Create a new migration (developers only)
|
|
uv run nextcloud-mcp-server db migrate "description of changes"
|
|
|
|
# Downgrade database by one version (emergency use only)
|
|
uv run nextcloud-mcp-server db downgrade
|
|
|
|
Direct Alembic Usage
|
|
--------------------
|
|
You can also use Alembic commands directly:
|
|
|
|
# Specify database URL via -x flag
|
|
uv run alembic -x database_url=sqlite+aiosqlite:////path/to/tokens.db upgrade head
|
|
|
|
# Or set in alembic.ini and run
|
|
uv run alembic upgrade head
|
|
uv run alembic current
|
|
uv run alembic history
|
|
|
|
Writing Migrations
|
|
------------------
|
|
Since we don't use SQLAlchemy models, migrations are written with raw SQL:
|
|
|
|
def upgrade() -> None:
|
|
op.execute("""
|
|
ALTER TABLE refresh_tokens
|
|
ADD COLUMN new_field TEXT
|
|
""")
|
|
|
|
def downgrade() -> None:
|
|
# SQLite doesn't support DROP COLUMN, use table recreation
|
|
op.execute("""
|
|
CREATE TABLE refresh_tokens_new AS
|
|
SELECT user_id, encrypted_token, ... FROM refresh_tokens
|
|
""")
|
|
op.execute("DROP TABLE refresh_tokens")
|
|
op.execute("ALTER TABLE refresh_tokens_new RENAME TO refresh_tokens")
|
|
|
|
Migration File Naming
|
|
---------------------
|
|
Format: YYYYMMDD_HHMM_<revision>_<slug>.py
|
|
Example: 20251217_2200_001_initial_schema.py
|
|
|
|
Notes
|
|
-----
|
|
- Migrations run automatically when RefreshTokenStorage.initialize() is called
|
|
- Existing databases are automatically stamped with the initial version
|
|
- SQLite has limited ALTER TABLE support - complex changes require table recreation
|