fix(translate): add missing target_languages column to production DB

Migration 2a7b8c9d0e1f adds target_languages (JSON) to translation_jobs.
Uses ADD COLUMN IF NOT EXISTS for idempotent PostgreSQL deployment.

Fixes 500 error on GET /api/translate/jobs:
  column translation_jobs.target_languages does not exist

Migration chain is now clean: 5 linear revisions, no orphans.
This commit is contained in:
2026-05-14 23:51:25 +03:00
parent cc1e57088d
commit 6717e2551d

View File

@@ -0,0 +1,67 @@
"""Add target_languages column to translation_jobs (multi-language support)
Revision ID: 2a7b8c9d0e1f
Revises: 8dd0a93af539
Create Date: 2026-05-14 23:55:00.000000
"""
from collections.abc import Sequence
import sqlalchemy as sa
from alembic import op
# revision identifiers, used by Alembic.
revision: str = "2a7b8c9d0e1f"
down_revision: str | Sequence[str] | None = "8dd0a93af539"
branch_labels: str | Sequence[str] | None = None
depends_on: str | Sequence[str] | None = None
def upgrade() -> None:
"""Add target_languages column to translation_jobs.
Production PostgreSQL may be missing this column if the initial
migration (ed310b33f02c) was applied from a version that predated
the multi-language support feature. This migration safely adds it
with IF NOT EXISTS on PostgreSQL, and handles SQLite explicitly.
"""
bind = op.get_bind()
inspector = sa.inspect(bind)
columns = [c["name"] for c in inspector.get_columns("translation_jobs")]
if "target_languages" in columns:
# Column already exists — nothing to do
return
if bind.engine.name == "sqlite":
op.add_column(
"translation_jobs",
sa.Column(
"target_languages",
sa.JSON(),
nullable=True,
comment="List of BCP-47 target language codes (multi-language support)",
),
)
else:
# PostgreSQL and others: use IF NOT EXISTS for safety
op.execute(
"ALTER TABLE translation_jobs "
"ADD COLUMN IF NOT EXISTS target_languages JSON "
"DEFAULT NULL"
)
def downgrade() -> None:
"""Drop target_languages column from translation_jobs."""
bind = op.get_bind()
if bind.engine.name == "sqlite":
inspector = sa.inspect(bind)
columns = [c["name"] for c in inspector.get_columns("translation_jobs")]
if "target_languages" in columns:
op.drop_column("translation_jobs", "target_languages")
else:
op.execute(
"ALTER TABLE translation_jobs DROP COLUMN IF EXISTS target_languages"
)