# Начальная схема: MOBILEDE_cars, MOBILEDE_images, MOBILEDE_sync_runs from typing import Sequence, Union from alembic import op import sqlalchemy as sa revision: str = "001_initial" down_revision: Union[str, None] = None branch_labels: Union[str, Sequence[str], None] = None depends_on: Union[str, Sequence[str], None] = None def _schema_name() -> str | None: bind = op.get_bind() return "public" if bind.dialect.name == "postgresql" else None def _table_exists(table_name: str) -> bool: inspector = sa.inspect(op.get_bind()) return table_name in inspector.get_table_names(schema=_schema_name()) def _index_exists(table_name: str, index_name: str) -> bool: if not _table_exists(table_name): return False inspector = sa.inspect(op.get_bind()) indexes = inspector.get_indexes(table_name, schema=_schema_name()) return any(index.get("name") == index_name for index in indexes) def upgrade() -> None: # Таблица MOBILEDE_cars — аукционные машины с MOBILEDE if not _table_exists("MOBILEDE_cars"): op.create_table( "MOBILEDE_cars", sa.Column("id", sa.BigInteger, primary_key=True, autoincrement=True), sa.Column("parser_id", sa.String(50), nullable=False, unique=True), sa.Column("brand", sa.String(50), nullable=False), sa.Column("model", sa.String(50), nullable=False), sa.Column("year", sa.Integer, nullable=True), sa.Column("price", sa.BigInteger, nullable=True), sa.Column("currency", sa.String(10), nullable=False, server_default="USD"), sa.Column("mileage", sa.Integer, nullable=False, server_default="0"), sa.Column("country", sa.String(10), nullable=False, server_default="NA"), sa.Column("is_sold", sa.Boolean, nullable=False, server_default=sa.text("false")), sa.Column("color", sa.String, nullable=False, server_default="other"), sa.Column("drive", sa.String(10), nullable=True), sa.Column("gearbox", sa.String(10), nullable=True), sa.Column("steering_wheel", sa.String(10), nullable=True), sa.Column("body_type", sa.String(20), nullable=False, server_default="OTHER"), sa.Column("engine_volume", sa.Integer, nullable=True), sa.Column("selling_type", sa.String(20), nullable=False, server_default="NA"), sa.Column("one_owner", sa.Boolean, nullable=False, server_default=sa.text("false")), sa.Column("new_car", sa.Boolean, nullable=False, server_default=sa.text("false")), sa.Column("is_hidden", sa.Boolean, nullable=False, server_default=sa.text("false")), sa.Column("origin", sa.String(20), nullable=False, server_default="NA"), sa.Column("origin_url", sa.String, nullable=False), sa.Column("origin_id", sa.String, nullable=False, unique=True), sa.Column("is_damaged", sa.Boolean, nullable=False, server_default=sa.text("false")), sa.Column("evaluation", sa.String, nullable=True), sa.Column("non_smoking", sa.Boolean, nullable=False, server_default=sa.text("true")), sa.Column("rental", sa.Boolean, nullable=False, server_default=sa.text("false")), sa.Column("repair_history", sa.Boolean, nullable=False, server_default=sa.text("false")), sa.Column("slug", sa.String, nullable=False), sa.Column("last_seen_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now()), ) if not _index_exists("MOBILEDE_cars", "ix_MOBILEDE_cars_origin_url"): op.create_index("ix_MOBILEDE_cars_origin_url", "MOBILEDE_cars", ["origin_url"]) if not _index_exists("MOBILEDE_cars", "ix_MOBILEDE_cars_origin_id"): op.create_index("ix_MOBILEDE_cars_origin_id", "MOBILEDE_cars", ["origin_id"], unique=True) # Таблица MOBILEDE_images — изображения машин if not _table_exists("MOBILEDE_images"): op.create_table( "MOBILEDE_images", sa.Column("id", sa.BigInteger, primary_key=True, autoincrement=True), sa.Column("fullres_image", sa.String, nullable=False), sa.Column("preview_image", sa.String, nullable=False), sa.Column("order_index", sa.Integer, nullable=False), sa.Column("car_id", sa.Integer, sa.ForeignKey("MOBILEDE_cars.id", ondelete="CASCADE"), nullable=False), ) # Таблица MOBILEDE_sync_runs — логирование синхронизаций if not _table_exists("MOBILEDE_sync_runs"): op.create_table( "MOBILEDE_sync_runs", sa.Column("id", sa.BigInteger, primary_key=True, autoincrement=True), sa.Column("started_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now()), sa.Column("finished_at", sa.DateTime(timezone=True), nullable=True), sa.Column("status", sa.Text, nullable=False), sa.Column("lane", sa.Text, nullable=False), sa.Column("ids_fetched", sa.Integer, nullable=False, server_default="0"), sa.Column("cars_upserted", sa.Integer, nullable=False, server_default="0"), sa.Column("cars_failed", sa.Integer, nullable=False, server_default="0"), sa.Column("images_upserted", sa.Integer, nullable=False, server_default="0"), sa.Column("error_summary", sa.Text, nullable=True), ) def downgrade() -> None: # Миграция оставлена только для совместимости с общей production-базой. pass