"""multi-language translation tables

Revision ID: ed310b33f02c
Revises: 
Create Date: 2026-05-14 15:35:03.167031

"""
from collections.abc import Sequence

import sqlalchemy as sa

from alembic import op

# revision identifiers, used by Alembic.
revision: str = 'ed310b33f02c'
down_revision: str | Sequence[str] | None = None
branch_labels: str | Sequence[str] | None = None
depends_on: str | Sequence[str] | None = None


def upgrade() -> None:
    """Upgrade schema."""
    # ### commands auto generated by Alembic - please adjust! ###
    op.create_table('environments',
    sa.Column('id', sa.String(), nullable=False),
    sa.Column('name', sa.String(), nullable=False),
    sa.Column('url', sa.String(), nullable=False),
    sa.Column('credentials_id', sa.String(), nullable=False),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_table('terminology_dictionaries',
    sa.Column('id', sa.String(), nullable=False),
    sa.Column('name', sa.String(), nullable=False),
    sa.Column('description', sa.Text(), nullable=True),
    sa.Column('source_dialect', sa.String(), nullable=False),
    sa.Column('target_dialect', sa.String(), nullable=False),
    sa.Column('source_language', sa.String(), nullable=True, comment='[DEPRECATED: use per-entry source_language]'),
    sa.Column('target_language', sa.String(), nullable=True, comment='[DEPRECATED: use per-entry target_language]'),
    sa.Column('is_active', sa.Boolean(), nullable=True),
    sa.Column('created_by', sa.String(), nullable=True),
    sa.Column('created_at', sa.DateTime(), nullable=True),
    sa.Column('updated_at', sa.DateTime(), nullable=True),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_table('translation_jobs',
    sa.Column('id', sa.String(), nullable=False),
    sa.Column('name', sa.String(), nullable=False),
    sa.Column('description', sa.Text(), nullable=True),
    sa.Column('source_dialect', sa.String(), nullable=False),
    sa.Column('target_dialect', sa.String(), nullable=False),
    sa.Column('database_dialect', sa.String(), nullable=True, comment='Detected dialect from Superset connection at save time'),
    sa.Column('status', sa.String(), nullable=False),
    sa.Column('source_datasource_id', sa.String(), nullable=True, comment='Superset datasource ID'),
    sa.Column('source_table', sa.String(), nullable=True, comment='Source table name resolved from datasource'),
    sa.Column('target_schema', sa.String(), nullable=True, comment='Target table schema'),
    sa.Column('target_table', sa.String(), nullable=True, comment='Target table name'),
    sa.Column('source_key_cols', sa.JSON(), nullable=True, comment='Source key column names for composite key'),
    sa.Column('target_key_cols', sa.JSON(), nullable=True, comment='Target key column names for composite key'),
    sa.Column('translation_column', sa.String(), nullable=True, comment='Source column whose values will be translated'),
    sa.Column('target_column', sa.String(), nullable=True, comment='Target column for translated output (defaults to translation_column)'),
    sa.Column('context_columns', sa.JSON(), nullable=True, comment='Context column names included in LLM prompt'),
    sa.Column('target_language', sa.String(), nullable=True, comment='Target language code (e.g. en, ru) [DEPRECATED: use target_languages]'),
    sa.Column('source_language', sa.String(), nullable=True, comment='Fallback source language hint [DEPRECATED: auto-detected per row]'),
    sa.Column('target_languages', sa.JSON(), nullable=True, comment='List of BCP-47 target language codes (multi-language support)'),
    sa.Column('provider_id', sa.String(), nullable=True, comment='LLM provider ID'),
    sa.Column('batch_size', sa.Integer(), nullable=False, comment='Records per batch'),
    sa.Column('upsert_strategy', sa.String(), nullable=False, comment='MERGE, INSERT, UPDATE'),
    sa.Column('environment_id', sa.String(), nullable=True, comment='Superset environment ID for datasource access'),
    sa.Column('target_database_id', sa.String(), nullable=True, comment='Superset database ID for SQL Lab insert target'),
    sa.Column('created_by', sa.String(), nullable=True),
    sa.Column('created_at', sa.DateTime(), nullable=True),
    sa.Column('updated_at', sa.DateTime(), nullable=True),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_table('database_mappings',
    sa.Column('id', sa.String(), nullable=False),
    sa.Column('source_env_id', sa.String(), nullable=False),
    sa.Column('target_env_id', sa.String(), nullable=False),
    sa.Column('source_db_uuid', sa.String(), nullable=False),
    sa.Column('target_db_uuid', sa.String(), nullable=False),
    sa.Column('source_db_name', sa.String(), nullable=False),
    sa.Column('target_db_name', sa.String(), nullable=False),
    sa.Column('engine', sa.String(), nullable=True),
    sa.ForeignKeyConstraint(['source_env_id'], ['environments.id'], ),
    sa.ForeignKeyConstraint(['target_env_id'], ['environments.id'], ),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_table('dictionary_entries',
    sa.Column('id', sa.String(), nullable=False),
    sa.Column('dictionary_id', sa.String(), nullable=False),
    sa.Column('source_term', sa.String(), nullable=False),
    sa.Column('source_term_normalized', sa.String(), nullable=False),
    sa.Column('target_term', sa.String(), nullable=False),
    sa.Column('source_language', sa.String(), nullable=False, comment='BCP-47 source language code'),
    sa.Column('target_language', sa.String(), nullable=False, comment='BCP-47 target language code'),
    sa.Column('context_notes', sa.Text(), nullable=True),
    sa.Column('context_data', sa.JSON(), nullable=True, comment='Structured context for term usage'),
    sa.Column('usage_notes', sa.Text(), nullable=True, comment='Usage guidance for the term mapping'),
    sa.Column('has_context', sa.Boolean(), nullable=True, comment='Whether context_data is populated'),
    sa.Column('context_source', sa.String(), nullable=True, comment='auto|auto_with_edits|manual|bulk'),
    sa.Column('origin_source_language', sa.String(), nullable=True, comment='Original source language of the term'),
    sa.Column('origin_run_id', sa.String(), nullable=True, comment='Run ID from which this correction originated'),
    sa.Column('origin_row_key', sa.String(), nullable=True, comment='Row key within the run that triggered this correction'),
    sa.Column('origin_user_id', sa.String(), nullable=True, comment='User who submitted the correction'),
    sa.Column('created_at', sa.DateTime(), nullable=True),
    sa.Column('updated_at', sa.DateTime(), nullable=True),
    sa.ForeignKeyConstraint(['dictionary_id'], ['terminology_dictionaries.id'], ),
    sa.PrimaryKeyConstraint('id'),
    sa.UniqueConstraint('dictionary_id', 'source_term_normalized', 'source_language', 'target_language', name='uq_dict_source_term_lang')
    )
    op.create_index('idx_dict_entry_lang', 'dictionary_entries', ['source_language', 'target_language'], unique=False)
    op.create_index('idx_dict_has_context', 'dictionary_entries', ['has_context'], unique=False)
    op.create_index(op.f('ix_dictionary_entries_dictionary_id'), 'dictionary_entries', ['dictionary_id'], unique=False)
    op.create_table('migration_jobs',
    sa.Column('id', sa.String(), nullable=False),
    sa.Column('source_env_id', sa.String(), nullable=False),
    sa.Column('target_env_id', sa.String(), nullable=False),
    sa.Column('status', sa.Enum('PENDING', 'RUNNING', 'COMPLETED', 'FAILED', 'AWAITING_MAPPING', name='migrationstatus'), nullable=True),
    sa.Column('replace_db', sa.Boolean(), nullable=True),
    sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('(CURRENT_TIMESTAMP)'), nullable=True),
    sa.ForeignKeyConstraint(['source_env_id'], ['environments.id'], ),
    sa.ForeignKeyConstraint(['target_env_id'], ['environments.id'], ),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_table('resource_mappings',
    sa.Column('id', sa.String(), nullable=False),
    sa.Column('environment_id', sa.String(), nullable=False),
    sa.Column('resource_type', sa.Enum('CHART', 'DATASET', 'DASHBOARD', name='resourcetype'), nullable=False),
    sa.Column('uuid', sa.String(), nullable=False),
    sa.Column('remote_integer_id', sa.String(), nullable=False),
    sa.Column('resource_name', sa.String(), nullable=True),
    sa.Column('last_synced_at', sa.DateTime(timezone=True), server_default=sa.text('(CURRENT_TIMESTAMP)'), nullable=True),
    sa.ForeignKeyConstraint(['environment_id'], ['environments.id'], ),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_table('translation_job_dictionaries',
    sa.Column('id', sa.String(), nullable=False),
    sa.Column('job_id', sa.String(), nullable=False),
    sa.Column('dictionary_id', sa.String(), nullable=False),
    sa.Column('created_at', sa.DateTime(), nullable=True),
    sa.ForeignKeyConstraint(['dictionary_id'], ['terminology_dictionaries.id'], ),
    sa.ForeignKeyConstraint(['job_id'], ['translation_jobs.id'], ),
    sa.PrimaryKeyConstraint('id'),
    sa.UniqueConstraint('job_id', 'dictionary_id', name='uq_job_dictionary')
    )
    op.create_index(op.f('ix_translation_job_dictionaries_dictionary_id'), 'translation_job_dictionaries', ['dictionary_id'], unique=False)
    op.create_index(op.f('ix_translation_job_dictionaries_job_id'), 'translation_job_dictionaries', ['job_id'], unique=False)
    op.create_table('translation_runs',
    sa.Column('id', sa.String(), nullable=False),
    sa.Column('job_id', sa.String(), nullable=False),
    sa.Column('status', sa.String(), nullable=False),
    sa.Column('trigger_type', sa.String(), nullable=True, comment='manual, scheduled, retry, baseline_expired'),
    sa.Column('started_at', sa.DateTime(), nullable=True),
    sa.Column('completed_at', sa.DateTime(), nullable=True),
    sa.Column('error_message', sa.Text(), nullable=True),
    sa.Column('total_records', sa.Integer(), nullable=True),
    sa.Column('successful_records', sa.Integer(), nullable=True),
    sa.Column('failed_records', sa.Integer(), nullable=True),
    sa.Column('skipped_records', sa.Integer(), nullable=True),
    sa.Column('insert_status', sa.String(), nullable=True, comment='Status of the Superset insert/update operation'),
    sa.Column('superset_execution_id', sa.String(), nullable=True, comment='Superset execution/task ID'),
    sa.Column('superset_execution_log', sa.JSON(), nullable=True, comment='Superset execution log output'),
    sa.Column('config_snapshot', sa.JSON(), nullable=True, comment='Snapshot of job config at run creation time'),
    sa.Column('key_hash', sa.String(), nullable=True, comment='Hash of source key fields for dedup'),
    sa.Column('config_hash', sa.String(), nullable=True, comment='Hash of translation configuration state'),
    sa.Column('dict_snapshot_hash', sa.String(), nullable=True, comment='Hash of dictionary state at run time'),
    sa.Column('created_by', sa.String(), nullable=True),
    sa.Column('created_at', sa.DateTime(), nullable=True),
    sa.ForeignKeyConstraint(['job_id'], ['translation_jobs.id'], ),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_index(op.f('ix_translation_runs_job_id'), 'translation_runs', ['job_id'], unique=False)
    op.create_table('translation_schedules',
    sa.Column('id', sa.String(), nullable=False),
    sa.Column('job_id', sa.String(), nullable=False),
    sa.Column('cron_expression', sa.String(), nullable=False),
    sa.Column('timezone', sa.String(), nullable=False),
    sa.Column('is_active', sa.Boolean(), nullable=True),
    sa.Column('last_run_at', sa.DateTime(), nullable=True),
    sa.Column('next_run_at', sa.DateTime(), nullable=True),
    sa.Column('execution_mode', sa.String(), nullable=False, comment='full, new_key_only'),
    sa.Column('created_by', sa.String(), nullable=True),
    sa.Column('created_at', sa.DateTime(), nullable=True),
    sa.Column('updated_at', sa.DateTime(), nullable=True),
    sa.ForeignKeyConstraint(['job_id'], ['translation_jobs.id'], ),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_index(op.f('ix_translation_schedules_job_id'), 'translation_schedules', ['job_id'], unique=False)
    op.create_table('translation_batches',
    sa.Column('id', sa.String(), nullable=False),
    sa.Column('run_id', sa.String(), nullable=False),
    sa.Column('batch_index', sa.Integer(), nullable=False),
    sa.Column('status', sa.String(), nullable=False),
    sa.Column('total_records', sa.Integer(), nullable=True),
    sa.Column('successful_records', sa.Integer(), nullable=True),
    sa.Column('failed_records', sa.Integer(), nullable=True),
    sa.Column('started_at', sa.DateTime(), nullable=True),
    sa.Column('completed_at', sa.DateTime(), nullable=True),
    sa.Column('created_at', sa.DateTime(), nullable=True),
    sa.ForeignKeyConstraint(['run_id'], ['translation_runs.id'], ),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_index(op.f('ix_translation_batches_run_id'), 'translation_batches', ['run_id'], unique=False)
    op.create_table('translation_events',
    sa.Column('id', sa.String(), nullable=False),
    sa.Column('job_id', sa.String(), nullable=False),
    sa.Column('run_id', sa.String(), nullable=True),
    sa.Column('event_type', sa.String(), nullable=False),
    sa.Column('event_data', sa.JSON(), nullable=True),
    sa.Column('created_by', sa.String(), nullable=True),
    sa.Column('created_at', sa.DateTime(), nullable=True),
    sa.ForeignKeyConstraint(['job_id'], ['translation_jobs.id'], ),
    sa.ForeignKeyConstraint(['run_id'], ['translation_runs.id'], ),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_index(op.f('ix_translation_events_job_id'), 'translation_events', ['job_id'], unique=False)
    op.create_index(op.f('ix_translation_events_run_id'), 'translation_events', ['run_id'], unique=False)
    op.create_table('translation_metric_snapshots',
    sa.Column('id', sa.String(), nullable=False),
    sa.Column('job_id', sa.String(), nullable=False),
    sa.Column('run_id', sa.String(), nullable=True),
    sa.Column('key_hash', sa.String(), nullable=False, comment='Hash of dimension key fields for aggregation'),
    sa.Column('config_hash', sa.String(), nullable=True, comment='Hash of translation configuration state'),
    sa.Column('dict_snapshot_hash', sa.String(), nullable=True, comment='Hash of dictionary state at capture time'),
    sa.Column('covers_events_before', sa.DateTime(), nullable=True, comment='Indicates snapshot covers events before this timestamp'),
    sa.Column('total_jobs', sa.Integer(), nullable=True),
    sa.Column('total_runs', sa.Integer(), nullable=True),
    sa.Column('total_records', sa.Integer(), nullable=True),
    sa.Column('successful_records', sa.Integer(), nullable=True),
    sa.Column('failed_records', sa.Integer(), nullable=True),
    sa.Column('skipped_records', sa.Integer(), nullable=True),
    sa.Column('avg_duration_ms', sa.Integer(), nullable=True),
    sa.Column('p50_duration_ms', sa.Integer(), nullable=True),
    sa.Column('p95_duration_ms', sa.Integer(), nullable=True),
    sa.Column('p99_duration_ms', sa.Integer(), nullable=True),
    sa.Column('snapshot_date', sa.DateTime(), nullable=False),
    sa.Column('created_at', sa.DateTime(), nullable=True),
    sa.ForeignKeyConstraint(['job_id'], ['translation_jobs.id'], ),
    sa.ForeignKeyConstraint(['run_id'], ['translation_runs.id'], ),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_index('ix_metric_snapshots_job_date', 'translation_metric_snapshots', ['job_id', 'snapshot_date'], unique=False)
    op.create_index(op.f('ix_translation_metric_snapshots_job_id'), 'translation_metric_snapshots', ['job_id'], unique=False)
    op.create_index(op.f('ix_translation_metric_snapshots_run_id'), 'translation_metric_snapshots', ['run_id'], unique=False)
    op.create_table('translation_preview_sessions',
    sa.Column('id', sa.String(), nullable=False),
    sa.Column('job_id', sa.String(), nullable=False),
    sa.Column('run_id', sa.String(), nullable=True),
    sa.Column('status', sa.String(), nullable=False),
    sa.Column('created_by', sa.String(), nullable=True),
    sa.Column('created_at', sa.DateTime(), nullable=True),
    sa.Column('expires_at', sa.DateTime(), nullable=True),
    sa.ForeignKeyConstraint(['job_id'], ['translation_jobs.id'], ),
    sa.ForeignKeyConstraint(['run_id'], ['translation_runs.id'], ),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_index(op.f('ix_translation_preview_sessions_job_id'), 'translation_preview_sessions', ['job_id'], unique=False)
    op.create_table('translation_run_language_stats',
    sa.Column('id', sa.String(), nullable=False),
    sa.Column('run_id', sa.String(), nullable=False),
    sa.Column('language_code', sa.String(), nullable=False, comment='BCP-47 language code'),
    sa.Column('total_rows', sa.Integer(), nullable=True),
    sa.Column('translated_rows', sa.Integer(), nullable=True),
    sa.Column('failed_rows', sa.Integer(), nullable=True),
    sa.Column('skipped_rows', sa.Integer(), nullable=True),
    sa.Column('token_count', sa.Integer(), nullable=True),
    sa.Column('estimated_cost', sa.Float(), nullable=True),
    sa.ForeignKeyConstraint(['run_id'], ['translation_runs.id'], ),
    sa.PrimaryKeyConstraint('id'),
    sa.UniqueConstraint('run_id', 'language_code', name='uq_run_language')
    )
    op.create_index('idx_rls_run', 'translation_run_language_stats', ['run_id'], unique=False)
    op.create_table('translation_preview_records',
    sa.Column('id', sa.String(), nullable=False),
    sa.Column('session_id', sa.String(), nullable=False),
    sa.Column('source_sql', sa.Text(), nullable=True),
    sa.Column('target_sql', sa.Text(), nullable=True),
    sa.Column('source_object_type', sa.String(), nullable=True),
    sa.Column('source_object_id', sa.String(), nullable=True),
    sa.Column('source_object_name', sa.String(), nullable=True),
    sa.Column('source_data', sa.JSON(), nullable=True, comment='Original source row key columns for upsert matching'),
    sa.Column('status', sa.String(), nullable=False),
    sa.Column('feedback', sa.Text(), nullable=True),
    sa.Column('created_at', sa.DateTime(), nullable=True),
    sa.ForeignKeyConstraint(['session_id'], ['translation_preview_sessions.id'], ),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_index(op.f('ix_translation_preview_records_session_id'), 'translation_preview_records', ['session_id'], unique=False)
    op.create_table('translation_records',
    sa.Column('id', sa.String(), nullable=False),
    sa.Column('batch_id', sa.String(), nullable=False),
    sa.Column('run_id', sa.String(), nullable=False),
    sa.Column('source_sql', sa.Text(), nullable=True),
    sa.Column('target_sql', sa.Text(), nullable=True),
    sa.Column('source_object_type', sa.String(), nullable=True),
    sa.Column('source_object_id', sa.String(), nullable=True),
    sa.Column('source_object_name', sa.String(), nullable=True),
    sa.Column('source_data', sa.JSON(), nullable=True, comment='Original source row key columns for upsert matching'),
    sa.Column('status', sa.String(), nullable=False),
    sa.Column('error_message', sa.Text(), nullable=True),
    sa.Column('token_count_input', sa.Integer(), nullable=True),
    sa.Column('token_count_output', sa.Integer(), nullable=True),
    sa.Column('translation_duration_ms', sa.Integer(), nullable=True),
    sa.Column('created_at', sa.DateTime(), nullable=True),
    sa.Column('llm_translation', sa.Text(), nullable=True, comment='[DEPRECATED: use TranslationLanguage]'),
    sa.Column('user_edit', sa.Text(), nullable=True, comment='[DEPRECATED: use TranslationLanguage]'),
    sa.Column('final_value', sa.Text(), nullable=True, comment='[DEPRECATED: use TranslationLanguage]'),
    sa.ForeignKeyConstraint(['batch_id'], ['translation_batches.id'], ),
    sa.ForeignKeyConstraint(['run_id'], ['translation_runs.id'], ),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_index(op.f('ix_translation_records_batch_id'), 'translation_records', ['batch_id'], unique=False)
    op.create_index(op.f('ix_translation_records_run_id'), 'translation_records', ['run_id'], unique=False)
    op.create_index('ix_translation_records_run_status', 'translation_records', ['run_id', 'status'], unique=False)
    op.create_table('translation_languages',
    sa.Column('id', sa.String(), nullable=False),
    sa.Column('record_id', sa.String(), nullable=False),
    sa.Column('language_code', sa.String(), nullable=False, comment='BCP-47 language code'),
    sa.Column('source_language_detected', sa.String(), nullable=True, comment="BCP-47 or 'und' for undetermined"),
    sa.Column('translated_value', sa.Text(), nullable=True, comment='LLM-generated translation'),
    sa.Column('user_edit', sa.Text(), nullable=True, comment='User-edited translation'),
    sa.Column('final_value', sa.Text(), nullable=True, comment='Final resolved value (translated or user edit)'),
    sa.Column('status', sa.String(), nullable=True, comment='pending|translated|approved|edited|rejected|failed|skipped'),
    sa.Column('error_message', sa.Text(), nullable=True),
    sa.Column('created_at', sa.DateTime(timezone=True), nullable=True),
    sa.ForeignKeyConstraint(['record_id'], ['translation_records.id'], ),
    sa.PrimaryKeyConstraint('id'),
    sa.UniqueConstraint('record_id', 'language_code', name='uq_record_language')
    )
    op.create_index('idx_tl_language', 'translation_languages', ['language_code'], unique=False)
    op.create_index('idx_tl_record_lang', 'translation_languages', ['record_id', 'language_code'], unique=False)
    op.create_table('translation_preview_languages',
    sa.Column('id', sa.String(), nullable=False),
    sa.Column('preview_record_id', sa.String(), nullable=False),
    sa.Column('language_code', sa.String(), nullable=False, comment='BCP-47 language code'),
    sa.Column('source_language_detected', sa.String(), nullable=True, comment="BCP-47 or 'und'"),
    sa.Column('translated_value', sa.Text(), nullable=True),
    sa.Column('user_edit', sa.Text(), nullable=True),
    sa.Column('final_value', sa.Text(), nullable=True),
    sa.Column('status', sa.String(), nullable=True, comment='pending|approved|edited|rejected'),
    sa.Column('created_at', sa.DateTime(timezone=True), nullable=True),
    sa.ForeignKeyConstraint(['preview_record_id'], ['translation_preview_records.id'], ),
    sa.PrimaryKeyConstraint('id'),
    sa.UniqueConstraint('preview_record_id', 'language_code', name='uq_preview_record_language')
    )
    # ### end Alembic commands ###


def downgrade() -> None:
    """Downgrade schema."""
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_table('translation_preview_languages')
    op.drop_index('idx_tl_record_lang', table_name='translation_languages')
    op.drop_index('idx_tl_language', table_name='translation_languages')
    op.drop_table('translation_languages')
    op.drop_index('ix_translation_records_run_status', table_name='translation_records')
    op.drop_index(op.f('ix_translation_records_run_id'), table_name='translation_records')
    op.drop_index(op.f('ix_translation_records_batch_id'), table_name='translation_records')
    op.drop_table('translation_records')
    op.drop_index(op.f('ix_translation_preview_records_session_id'), table_name='translation_preview_records')
    op.drop_table('translation_preview_records')
    op.drop_index('idx_rls_run', table_name='translation_run_language_stats')
    op.drop_table('translation_run_language_stats')
    op.drop_index(op.f('ix_translation_preview_sessions_job_id'), table_name='translation_preview_sessions')
    op.drop_table('translation_preview_sessions')
    op.drop_index(op.f('ix_translation_metric_snapshots_run_id'), table_name='translation_metric_snapshots')
    op.drop_index(op.f('ix_translation_metric_snapshots_job_id'), table_name='translation_metric_snapshots')
    op.drop_index('ix_metric_snapshots_job_date', table_name='translation_metric_snapshots')
    op.drop_table('translation_metric_snapshots')
    op.drop_index(op.f('ix_translation_events_run_id'), table_name='translation_events')
    op.drop_index(op.f('ix_translation_events_job_id'), table_name='translation_events')
    op.drop_table('translation_events')
    op.drop_index(op.f('ix_translation_batches_run_id'), table_name='translation_batches')
    op.drop_table('translation_batches')
    op.drop_index(op.f('ix_translation_schedules_job_id'), table_name='translation_schedules')
    op.drop_table('translation_schedules')
    op.drop_index(op.f('ix_translation_runs_job_id'), table_name='translation_runs')
    op.drop_table('translation_runs')
    op.drop_index(op.f('ix_translation_job_dictionaries_job_id'), table_name='translation_job_dictionaries')
    op.drop_index(op.f('ix_translation_job_dictionaries_dictionary_id'), table_name='translation_job_dictionaries')
    op.drop_table('translation_job_dictionaries')
    op.drop_table('resource_mappings')
    op.drop_table('migration_jobs')
    op.drop_index(op.f('ix_dictionary_entries_dictionary_id'), table_name='dictionary_entries')
    op.drop_index('idx_dict_has_context', table_name='dictionary_entries')
    op.drop_index('idx_dict_entry_lang', table_name='dictionary_entries')
    op.drop_table('dictionary_entries')
    op.drop_table('database_mappings')
    op.drop_table('translation_jobs')
    op.drop_table('terminology_dictionaries')
    op.drop_table('environments')
    # ### end Alembic commands ###
