This commit is contained in:
Artem Tsyrulnikov
2026-01-15 22:02:16 +03:00
parent 6ec26c96e3
commit 049024ebe8
72 changed files with 2417 additions and 2054 deletions

View File

@@ -59,20 +59,55 @@ uv run pytest tests/test_file.py::test_function_name
### Database Migrations
```bash
# Create a new migration (auto-generated based on model changes)
make migrate-create # or: export $(cat .env | xargs) && aerich migrate
make migrate-create # or: source .env && aerich migrate
# Apply migrations
make migrate-up # or: export $(cat .env | xargs) && aerich upgrade
make migrate-up # or: source .env && aerich upgrade
# Rollback one migration
make migrate-down # or: export $(cat .env | xargs) && aerich downgrade
# NOTE: For custom constraints (CHECK, custom indexes, etc.) that cannot be defined
# in Tortoise ORM models, create empty migrations and edit them manually:
export $(cat .env | xargs) && aerich migrate --name "add_check_constraint" --empty
# Then edit the created file and add `# ruff: noqa` and `# mypy: ignore-errors` at the top.
make migrate-down # or: source .env && aerich downgrade
```
**Important Migration Workflow:**
1. **For simple model changes**: Let aerich auto-generate the migration:
```bash
source .env && aerich migrate --name "descriptive_name"
```
2. **For complex refactorings** (table renames, data migration, etc.):
- **FIRST**: Update domain models to reflect the new structure
- **THEN**: Run `aerich migrate` to auto-generate the migration file
- **FINALLY**: Edit the generated file to add data migration logic
Example workflow:
```bash
# 1. Update models in src/domain/
# 2. Generate migration (will create base ALTER TABLE statements)
source .env && aerich migrate --name "refactor_tables"
# 3. Edit the generated file in migrations/models/ to add:
# - Data migration SQL (INSERT ... SELECT)
# - Proper ordering of operations
# - Comments explaining complex logic
```
3. **For custom constraints** (CHECK, custom indexes, etc.):
```bash
source .env && aerich migrate --name "add_check_constraint" --empty
# Then edit and add: # ruff: noqa and # mypy: ignore-errors at the top
```
**Migration Best Practices:**
- Always test migrations on a copy of production data
- Use transactions (`RUN_IN_TRANSACTION = True`)
- Add comments explaining complex data transformations
- For table renames with data migration:
1. Rename old table to `old_*`
2. Create new table structure
3. Migrate data with `INSERT INTO new SELECT ... FROM old`
4. Drop old table last
- Include proper downgrade logic (even if it loses some data)
## Architecture
### Layered Architecture