Files

164 lines
3.6 KiB
Markdown
Raw Permalink Normal View History

# Database Migrations with Alembic
This guide explains how to set up and run database migrations using Alembic.
## Prerequisites
1. Database must be running (use Docker Compose)
2. Alembic must be installed: `poetry install` (already included in pyproject.toml)
## Quick Start
### 1. Start the Database
```bash
cd backend
docker-compose up -d db
```
### 2. Initialize Alembic (First Time Only)
```bash
# Install alembic if not already installed
poetry add alembic
# Initialize alembic
poetry run alembic init alembic
```
### 3. Configure Alembic
Update `alembic.ini`:
```ini
sqlalchemy.url = postgresql://postgres:postgres@localhost:5432/wealthwise
```
Update `alembic/env.py`:
```python
import asyncio
from sqlalchemy.ext.asyncio import create_async_engine, AsyncEngine
# Import your models
from app.models import User, Portfolio, Transaction
from app.models.base import BaseModel
# Set target metadata
target_metadata = BaseModel.metadata
def do_run_migrations(connection):
context.configure(
connection=connection,
target_metadata=target_metadata,
compare_type=True,
)
with context.begin_transaction():
context.run_migrations()
async def run_migrations_online():
"""Run migrations in 'online' mode with async engine."""
configuration = config.get_section(config.config_ini_section)
# Convert sync URL to async URL
url = configuration['sqlalchemy.url'].replace(
'postgresql://', 'postgresql+asyncpg://'
)
connectable = create_async_engine(url)
async with connectable.connect() as connection:
await connection.run_sync(do_run_migrations)
await connectable.dispose()
if context.is_offline_mode():
run_migrations_offline()
else:
asyncio.run(run_migrations_online())
```
### 4. Create Initial Migration
```bash
# Generate migration script
poetry run alembic revision --autogenerate -m "Initial migration with user, portfolio, transaction"
# Apply migration
poetry run alembic upgrade head
```
## Common Commands
### Create a New Migration
```bash
# Auto-generate from model changes
poetry run alembic revision --autogenerate -m "Add new field to user"
# Create empty migration
poetry run alembic revision -m "Manual migration"
```
### Apply Migrations
```bash
# Upgrade to latest
poetry run alembic upgrade head
# Upgrade specific number of revisions
poetry run alembic upgrade +2
# Upgrade to specific revision
poetry run alembic upgrade abc123
```
### Rollback Migrations
```bash
# Downgrade one revision
poetry run alembic downgrade -1
# Downgrade to specific revision
poetry run alembic downgrade abc123
# Downgrade all the way
poetry run alembic downgrade base
```
### View Migration Status
```bash
# Current revision
poetry run alembic current
# History
poetry run alembic history --verbose
```
## Migration Best Practices
1. **Always review auto-generated migrations** before applying them
2. **Test migrations** on a copy of production data before running in production
3. **Never modify** existing migration files after they've been applied
4. **Use descriptive names** for migration messages
5. **One logical change per migration** (don't bundle unrelated changes)
## Troubleshooting
### Async Issues
If you encounter async-related errors, ensure you're using `create_async_engine` and `AsyncEngine` in `env.py`.
### Import Errors
Make sure all models are imported in `env.py`:
```python
from app.models import User, Portfolio, Transaction
```
### Connection Issues
Ensure the database is running and accessible:
```bash
docker-compose ps
# or
pg_isready -h localhost -p 5432 -U postgres
```