101 lines
3.9 KiB
Python
101 lines
3.9 KiB
Python
"""create iaai-specific storage tables
|
|
|
|
Revision ID: 0003_create_iaai_source_tables
|
|
Revises: 0002_extend_origin_enum_for_iaai
|
|
Create Date: 2026-04-09 00:00:00
|
|
"""
|
|
|
|
from typing import Sequence, Union
|
|
|
|
from alembic import op
|
|
|
|
|
|
# revision identifiers, used by Alembic.
|
|
revision: str = "0003_create_iaai_source_tables"
|
|
down_revision: Union[str, Sequence[str], None] = "0002_extend_origin_enum_for_iaai"
|
|
branch_labels: Union[str, Sequence[str], None] = None
|
|
depends_on: Union[str, Sequence[str], None] = None
|
|
|
|
|
|
def upgrade() -> None:
|
|
op.execute(
|
|
"""
|
|
CREATE TABLE IF NOT EXISTS public.iaai_cars (
|
|
id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
|
parser_id VARCHAR(50) NOT NULL UNIQUE,
|
|
brand VARCHAR(50) NOT NULL,
|
|
model VARCHAR(50) NOT NULL,
|
|
year INTEGER NULL,
|
|
price BIGINT NULL,
|
|
currency public.currencyenum NOT NULL DEFAULT 'USD',
|
|
mileage INTEGER NOT NULL DEFAULT 0,
|
|
country public.countryenum NOT NULL DEFAULT 'NA',
|
|
is_sold BOOLEAN NOT NULL DEFAULT FALSE,
|
|
color VARCHAR NOT NULL DEFAULT 'other',
|
|
drive public.driveenum NULL,
|
|
gearbox public.gearboxenum NULL,
|
|
steering_wheel public.steeringwheelenum NULL,
|
|
body_type public.bodytypeenum NOT NULL DEFAULT 'OTHER',
|
|
engine_volume INTEGER NULL,
|
|
selling_type public.sellingtypeenum NOT NULL DEFAULT 'NA',
|
|
one_owner BOOLEAN NOT NULL DEFAULT FALSE,
|
|
new_car BOOLEAN NOT NULL DEFAULT FALSE,
|
|
is_hidden BOOLEAN NOT NULL DEFAULT FALSE,
|
|
origin public.originenum NOT NULL DEFAULT 'NA',
|
|
origin_url VARCHAR NOT NULL,
|
|
origin_id VARCHAR NOT NULL UNIQUE,
|
|
is_damaged BOOLEAN NOT NULL DEFAULT FALSE,
|
|
evaluation VARCHAR NULL,
|
|
non_smoking BOOLEAN NOT NULL DEFAULT TRUE,
|
|
rental BOOLEAN NOT NULL DEFAULT FALSE,
|
|
repair_history BOOLEAN NOT NULL DEFAULT FALSE,
|
|
slug VARCHAR NOT NULL,
|
|
last_seen_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
)
|
|
"""
|
|
)
|
|
|
|
op.execute(
|
|
"""
|
|
CREATE TABLE IF NOT EXISTS public.iaai_images (
|
|
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
|
fullres_image VARCHAR NOT NULL,
|
|
preview_image VARCHAR NOT NULL,
|
|
order_index INTEGER NOT NULL,
|
|
car_id INTEGER NOT NULL REFERENCES public.iaai_cars(id) ON DELETE CASCADE
|
|
)
|
|
"""
|
|
)
|
|
|
|
op.execute(
|
|
"""
|
|
CREATE TABLE IF NOT EXISTS public.iaai_sync_runs (
|
|
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
|
started_at TIMESTAMPTZ NOT NULL,
|
|
finished_at TIMESTAMPTZ NULL,
|
|
status TEXT NOT NULL,
|
|
lane TEXT NOT NULL,
|
|
ids_fetched INTEGER NOT NULL DEFAULT 0,
|
|
cars_upserted INTEGER NOT NULL DEFAULT 0,
|
|
cars_failed INTEGER NOT NULL DEFAULT 0,
|
|
images_upserted INTEGER NOT NULL DEFAULT 0,
|
|
error_summary TEXT NULL
|
|
)
|
|
"""
|
|
)
|
|
|
|
op.execute("CREATE INDEX IF NOT EXISTS ix_iaai_images_car_id ON public.iaai_images (car_id)")
|
|
op.execute("CREATE INDEX IF NOT EXISTS ix_iaai_images_car_order ON public.iaai_images (car_id, order_index)")
|
|
op.execute("CREATE INDEX IF NOT EXISTS ix_iaai_cars_last_seen_id ON public.iaai_cars (last_seen_at DESC, id DESC)")
|
|
op.execute(
|
|
"CREATE INDEX IF NOT EXISTS ix_iaai_cars_active_feed ON public.iaai_cars "
|
|
"(last_seen_at DESC, id DESC) WHERE is_sold = FALSE AND is_hidden = FALSE"
|
|
)
|
|
op.execute("CREATE INDEX IF NOT EXISTS ix_iaai_sync_runs_started_at ON public.iaai_sync_runs (started_at)")
|
|
op.execute("CREATE INDEX IF NOT EXISTS ix_iaai_sync_runs_status ON public.iaai_sync_runs (status)")
|
|
|
|
|
|
def downgrade() -> None:
|
|
# Compatibility-only migration for shared production databases.
|
|
pass
|