104 lines
5.5 KiB
Python
104 lines
5.5 KiB
Python
# Начальная схема: 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
|