generated from john/python-template
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
# Database Rebuild Migration Workflow
|
||||
|
||||
This project uses an explicit **export/import rebuild workflow** for schema migration.
|
||||
|
||||
Policy:
|
||||
- Do not add runtime legacy-compatibility write paths.
|
||||
- Rebuild a fresh target database from current models.
|
||||
- Export current data/media, then import into the fresh target.
|
||||
|
||||
## Commands
|
||||
|
||||
### 1) Export current DB + uploads into a bundle
|
||||
|
||||
```bash
|
||||
uv run python tools/export_import_migration.py export --bundle-dir .migration-bundle
|
||||
```
|
||||
|
||||
Optional source overrides:
|
||||
- `--source-db <path-or-sqlalchemy-url>`
|
||||
- `--source-upload-dir <path>`
|
||||
|
||||
### 2) Import bundle into a fresh DB + uploads root
|
||||
|
||||
```bash
|
||||
uv run python tools/export_import_migration.py import --bundle-dir .migration-bundle --target-db .\data\transcription-new.db --target-upload-dir .\data-new
|
||||
```
|
||||
|
||||
### 3) One-shot export+import
|
||||
|
||||
```bash
|
||||
uv run python tools/export_import_migration.py migrate --bundle-dir .migration-bundle --target-db .\data\transcription-new.db --target-upload-dir .\data-new
|
||||
```
|
||||
|
||||
## What gets migrated
|
||||
|
||||
- Tables (in dependency order): `document_type`, `person_role`, `document`, `person`, `document_person`, `job`, `source`, `job_source`, `execution_attempt`.
|
||||
- Media tree under `UPLOAD_DIR`.
|
||||
|
||||
The bundle contains:
|
||||
- `database.json` (row export)
|
||||
- `uploads/` (copied media files)
|
||||
|
||||
Path normalization during export/import:
|
||||
- `source.file_path` is normalized to `documents/...` (upload-root-relative POSIX).
|
||||
- `person.portrait_path` is normalized to `persons/...` (upload-root-relative POSIX).
|
||||
|
||||
## Cutover
|
||||
|
||||
After importing to a fresh target:
|
||||
1. Stop the app.
|
||||
2. Point `DATABASE__*` and `UPLOAD_DIR` to the new targets.
|
||||
3. Start the app and run smoke checks (`/healthz`, create/upload/process one job).
|
||||
+2
-2
@@ -104,7 +104,7 @@ erDiagram
|
||||
| `death_date_raw` | `str \| None` | optional |
|
||||
| `death_place` | `str \| None` | optional |
|
||||
| `biography` | `str \| None` | optional |
|
||||
| `portrait_path` | `str \| None` | optional |
|
||||
| `portrait_path` | `str \| None` | optional upload-root-relative POSIX path (`persons/...`) |
|
||||
| `family_search_id` | `str \| None` | nullable unique |
|
||||
| `metadata_` | `dict[str, JsonValue] \| None` | stored as DB column `metadata` (`JSONBCompat`) |
|
||||
| `created_at` | `datetime` | default now |
|
||||
@@ -156,7 +156,7 @@ Index:
|
||||
| `page_number` | `int` | default `1`, `ge=1` |
|
||||
| `upload_name` | `str` | required |
|
||||
| `filename` | `str` | required |
|
||||
| `file_path` | `str` | required |
|
||||
| `file_path` | `str` | required upload-root-relative POSIX path (`documents/...`) |
|
||||
| `file_hash` | `str` | required |
|
||||
| `file_size_bytes` | `int` | `BigInteger`, non-null |
|
||||
| `raw_transcription` | `str \| None` | projection field |
|
||||
|
||||
Reference in New Issue
Block a user