@@ -1,4 +1,4 @@
# Начальная схема: cars, images, sync_runs
# Начальная схема: iaai_ cars, iaai_ images, iaai_ sync_runs
from typing import Sequence , Union
from alembic import op
@@ -10,70 +10,94 @@ 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 :
# Таблица cars — аукционные машины с IAAI
op . create_table (
" cars " ,
sa . Column ( " id " , sa . BigInteger , primary_key = True , autoincrement = True ) ,
sa . Column ( " parser_ id" , sa . String ( 50 ) , nullable = Fals e, unique = True ) ,
sa . Column ( " bran d" , sa . String ( 50 ) , nullable = False ) ,
sa . Column ( " model " , sa . String ( 50 ) , nullable = False ) ,
sa . Column ( " year " , sa . Integer , nullable = Tru e) ,
sa . Column ( " price " , sa . Big Integer, 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 ( 2 0) , nullable = False , server_default = " OTHER " ) ,
sa . Column ( " engine_volum e" , sa . Integer , nullable = True ) ,
sa . Column ( " selling_typ e" , sa . String ( 20 ) , nullable = False , server_default = " NA " ) ,
sa . Column ( " one_owner " , sa . Boolean , nullable = False , server_default = sa . text ( " false " ) ) ,
sa . Column ( " new_ca r " , sa . Boolean , nullable = False , server_default = sa . text ( " false " ) ) ,
sa . Column ( " is_hidden " , sa . Boolean , nullable = False , server_default = sa . text ( " false " ) ) ,
sa . Column ( " origi n" , 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_damage d" , 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 ( " fals e" ) ) ,
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 ( ) ) ,
)
op . create_index ( " ix_cars_origin_url " , " cars " , [ " origin_url " ] )
op . create_index ( " ix_cars_origin_id " , " cars " , [ " origin_id " ] , unique = True )
# Таблица iaai_ cars — аукционные машины с IAAI
if not _table_exists ( " iaai_cars " ) :
op . create_table (
" iaai_cars " ,
sa . Column ( " id " , sa . BigInteger , primary_key = Tru e, autoincrement = True ) ,
sa . Column ( " parser_i d" , sa . String ( 50 ) , nullable = False , unique = True ),
sa . Column ( " brand " , sa . String ( 50 ) , nullable = False ) ,
sa . Column ( " model " , sa . String ( 50 ) , nullable = Fals e) ,
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 ( 1 0) , nullable = True ) ,
sa . Column ( " body_typ e" , sa . String ( 20 ) , nullable = False , server_default = " OTHER " ) ,
sa . Column ( " engine_volum e" , sa . Integer , nullable = True ) ,
sa . Column ( " selling_type " , sa . String ( 20 ) , nullable = False , server_default = " NA " ) ,
sa . Column ( " o ne_owne r" , 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_hidde n" , 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_i d" , 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 ( " tru e" ) ) ,
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 ( ) ) ,
)
# Таблица images — изображения машин
op . create_table (
" 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 ( " cars.id " , ondelete = " CASCADE " ) , nullable = False ) ,
)
if not _index_exists ( " iaai_cars " , " ix_iaai_cars_origin_url " ) :
op . create_index ( " ix_iaai_cars_origin_url " , " iaai_cars " , [ " origin_url " ] )
if not _index_exists ( " iaai_cars " , " ix_iaai_cars_origin_id " ) :
op . create_index ( " ix_iaai_cars_origin_id " , " iaai_cars " , [ " origin_id " ] , unique = True )
# Таблица iaai_images — изображения машин
if not _table_exists ( " iaai_images " ) :
op . create_table (
" iaai_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 ( " iaai_cars.id " , ondelete = " CASCADE " ) , nullable = False ) ,
)
# Таблица iaai_sync_runs — логирование синхронизаций
if not _table_exists ( " iaai_sync_runs " ) :
op . create_table (
" iaai_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 ) ,
)
# Таблица sync_runs — логирование синхронизаций
op . create_table (
" 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 :
op . drop_table ( " sync_runs " )
op . drop_table ( " images " )
op . drop_table ( " cars " )
# Compatibility-only migration for shared production databases.
pass