Removed 6 legacy columns replaced by Phase 11 multi-language models:
- TranslationJob.target_language → target_languages (JSON)
- TranslationRecord.{llm_translation, user_edit, final_value} → TranslationLanguage
- TerminologyDictionary.{source_language, target_language} → DictionaryEntry per-entry
Affected files: model, schemas, 5 plugins, 4 test files
Alembic migration: aa1b2c3d4e5f (DROP COLUMN IF EXISTS)
Production DB: columns dropped via ALTER TABLE
Tests: 234 passed, 0 failed
68 lines
3.6 KiB
Python
68 lines
3.6 KiB
Python
"""Drop all deprecated columns from translate models
|
|
|
|
Deprecated columns removed:
|
|
- translation_jobs.target_language (use target_languages JSON instead)
|
|
- translation_records.llm_translation, user_edit, final_value (use TranslationLanguage instead)
|
|
- terminology_dictionaries.source_language, target_language (use per-entry DictionaryEntry instead)
|
|
|
|
Revision ID: aa1b2c3d4e5f
|
|
Revises: 2a7b8c9d0e1f
|
|
Create Date: 2026-05-14 23:59:00.000000
|
|
|
|
"""
|
|
from collections.abc import Sequence
|
|
|
|
import sqlalchemy as sa
|
|
|
|
from alembic import op
|
|
|
|
# revision identifiers, used by Alembic.
|
|
revision: str = "aa1b2c3d4e5f"
|
|
down_revision: str | Sequence[str] | None = "2a7b8c9d0e1f"
|
|
branch_labels: str | Sequence[str] | None = None
|
|
depends_on: str | Sequence[str] | None = None
|
|
|
|
|
|
def upgrade() -> None:
|
|
"""Drop all deprecated columns using DROP COLUMN IF EXISTS for safety."""
|
|
bind = op.get_bind()
|
|
if bind.engine.name == "sqlite":
|
|
inspector = sa.inspect(bind)
|
|
_drop_if_exists_sqlite(inspector, "translation_jobs", "target_language")
|
|
_drop_if_exists_sqlite(inspector, "translation_records", "llm_translation")
|
|
_drop_if_exists_sqlite(inspector, "translation_records", "user_edit")
|
|
_drop_if_exists_sqlite(inspector, "translation_records", "final_value")
|
|
_drop_if_exists_sqlite(inspector, "terminology_dictionaries", "source_language")
|
|
_drop_if_exists_sqlite(inspector, "terminology_dictionaries", "target_language")
|
|
else:
|
|
# PostgreSQL and others: use IF EXISTS
|
|
op.execute("ALTER TABLE translation_jobs DROP COLUMN IF EXISTS target_language")
|
|
op.execute("ALTER TABLE translation_records DROP COLUMN IF EXISTS llm_translation")
|
|
op.execute("ALTER TABLE translation_records DROP COLUMN IF EXISTS user_edit")
|
|
op.execute("ALTER TABLE translation_records DROP COLUMN IF EXISTS final_value")
|
|
op.execute("ALTER TABLE terminology_dictionaries DROP COLUMN IF EXISTS source_language")
|
|
op.execute("ALTER TABLE terminology_dictionaries DROP COLUMN IF EXISTS target_language")
|
|
|
|
|
|
def downgrade() -> None:
|
|
"""Restore all deprecated columns (for rollback)."""
|
|
op.add_column("translation_jobs", sa.Column("target_language", sa.String(), nullable=True,
|
|
comment="Target language code (e.g. en, ru) [DEPRECATED: use target_languages]"))
|
|
op.add_column("translation_records", sa.Column("llm_translation", sa.Text(), nullable=True,
|
|
comment="[DEPRECATED: use TranslationLanguage]"))
|
|
op.add_column("translation_records", sa.Column("user_edit", sa.Text(), nullable=True,
|
|
comment="[DEPRECATED: use TranslationLanguage]"))
|
|
op.add_column("translation_records", sa.Column("final_value", sa.Text(), nullable=True,
|
|
comment="[DEPRECATED: use TranslationLanguage]"))
|
|
op.add_column("terminology_dictionaries", sa.Column("source_language", sa.String(), nullable=True,
|
|
comment="[DEPRECATED: use per-entry source_language]"))
|
|
op.add_column("terminology_dictionaries", sa.Column("target_language", sa.String(), nullable=True,
|
|
comment="[DEPRECATED: use per-entry target_language]"))
|
|
|
|
|
|
def _drop_if_exists_sqlite(inspector, table: str, column: str) -> None:
|
|
"""Drop a column from a SQLite table only if it exists."""
|
|
columns = [c["name"] for c in inspector.get_columns(table)]
|
|
if column in columns:
|
|
op.drop_column(table, column)
|