Files
ozon-seller-kit/server/migrations/versions/51715d16e5c3_initial_v2_schema.py

204 lines
12 KiB
Python

"""initial v2 schema
Revision ID: 51715d16e5c3
Revises:
Create Date: 2026-08-15 10:06:57.793304
"""
from __future__ import annotations
from alembic import op
import sqlalchemy as sa
revision = '51715d16e5c3'
down_revision = None
branch_labels = None
depends_on = None
def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('attribute_values',
sa.Column('id', sa.BigInteger(), nullable=False),
sa.Column('attribute_id', sa.BigInteger(), nullable=False),
sa.Column('description_category_id', sa.BigInteger(), nullable=False),
sa.Column('type_id', sa.BigInteger(), nullable=False),
sa.Column('value', sa.String(length=512), nullable=False),
sa.Column('picture', sa.Text(), nullable=False),
sa.Column('info', sa.Text(), nullable=False),
sa.Column('lang', sa.String(length=8), nullable=False),
sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('(CURRENT_TIMESTAMP)'), nullable=False),
sa.PrimaryKeyConstraint('id', 'attribute_id', 'description_category_id', 'type_id')
)
op.create_table('category_attributes',
sa.Column('description_category_id', sa.BigInteger(), nullable=False),
sa.Column('type_id', sa.BigInteger(), nullable=False),
sa.Column('attribute_id', sa.BigInteger(), nullable=False),
sa.Column('name', sa.String(length=255), nullable=False),
sa.Column('description', sa.Text(), nullable=False),
sa.Column('type', sa.String(length=32), nullable=False),
sa.Column('dictionary_id', sa.BigInteger(), nullable=False),
sa.Column('group_id', sa.BigInteger(), nullable=True),
sa.Column('group_name', sa.String(length=255), nullable=False),
sa.Column('is_required', sa.Boolean(), nullable=False),
sa.Column('is_aspect', sa.Boolean(), nullable=False),
sa.Column('is_collection', sa.Boolean(), nullable=False),
sa.Column('max_value_count', sa.Integer(), nullable=False),
sa.Column('attribute_complex_id', sa.BigInteger(), nullable=True),
sa.Column('complex_is_collection', sa.Boolean(), nullable=False),
sa.Column('category_dependent', sa.Boolean(), nullable=False),
sa.Column('lang', sa.String(length=8), nullable=False),
sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('(CURRENT_TIMESTAMP)'), nullable=False),
sa.PrimaryKeyConstraint('description_category_id', 'type_id', 'attribute_id')
)
op.create_table('category_tree',
sa.Column('description_category_id', sa.BigInteger(), nullable=False),
sa.Column('parent_id', sa.BigInteger(), nullable=True),
sa.Column('category_name', sa.String(length=255), nullable=False),
sa.Column('type_id', sa.BigInteger(), nullable=True),
sa.Column('type_name', sa.String(length=255), nullable=False),
sa.Column('disabled', sa.Boolean(), nullable=False),
sa.Column('level', sa.Integer(), nullable=False),
sa.Column('lang', sa.String(length=8), nullable=False),
sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('(CURRENT_TIMESTAMP)'), nullable=False),
sa.PrimaryKeyConstraint('description_category_id')
)
op.create_index(op.f('ix_category_tree_parent_id'), 'category_tree', ['parent_id'], unique=False)
op.create_table('products',
sa.Column('id', sa.Uuid(), nullable=False),
sa.Column('user_id', sa.Uuid(), nullable=True),
sa.Column('stage', sa.Enum('collected', 'editing', 'ready', 'publishing', 'published', 'failed', 'archived', name='stage', native_enum=False, length=16), nullable=False),
sa.Column('source_platform', sa.String(length=16), nullable=True),
sa.Column('source_item_id', sa.String(length=64), nullable=True),
sa.Column('source_url', sa.Text(), nullable=True),
sa.Column('offer_id', sa.String(length=255), nullable=False),
sa.Column('ozon_product_id', sa.BigInteger(), nullable=True),
sa.Column('ozon_sku', sa.BigInteger(), nullable=True),
sa.Column('name', sa.Text(), nullable=False),
sa.Column('description', sa.Text(), nullable=False),
sa.Column('description_category_id', sa.BigInteger(), nullable=True),
sa.Column('type_id', sa.BigInteger(), nullable=True),
sa.Column('price', sa.Float(), nullable=True),
sa.Column('old_price', sa.Float(), nullable=True),
sa.Column('currency_code', sa.String(length=3), server_default='RUB', nullable=False),
sa.Column('vat', sa.String(length=8), server_default='0', nullable=False),
sa.Column('depth', sa.Float(), nullable=True),
sa.Column('width', sa.Float(), nullable=True),
sa.Column('height', sa.Float(), nullable=True),
sa.Column('dimension_unit', sa.String(length=4), server_default='mm', nullable=False),
sa.Column('weight', sa.Float(), nullable=True),
sa.Column('weight_unit', sa.String(length=4), server_default='g', nullable=False),
sa.Column('barcode', sa.String(length=64), nullable=True),
sa.Column('images', sa.JSON(), nullable=True),
sa.Column('primary_image', sa.Text(), nullable=True),
sa.Column('images360', sa.JSON(), nullable=True),
sa.Column('color_image', sa.Text(), nullable=True),
sa.Column('pdf_list', sa.JSON(), nullable=True),
sa.Column('promotions', sa.JSON(), nullable=True),
sa.Column('attributes', sa.JSON(), nullable=True),
sa.Column('complex_attributes', sa.JSON(), nullable=True),
sa.Column('raw', sa.JSON(), nullable=True),
sa.Column('pricing', sa.JSON(), nullable=True),
sa.Column('copy', sa.JSON(), nullable=True),
sa.Column('fx_rate', sa.Float(), nullable=True),
sa.Column('published_at', sa.DateTime(timezone=True), nullable=True),
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('(CURRENT_TIMESTAMP)'), nullable=False),
sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('(CURRENT_TIMESTAMP)'), nullable=False),
sa.Column('asset_counts', sa.JSON(), nullable=True),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_products_offer_id'), 'products', ['offer_id'], unique=False)
op.create_index(op.f('ix_products_ozon_product_id'), 'products', ['ozon_product_id'], unique=False)
op.create_index(op.f('ix_products_source_item_id'), 'products', ['source_item_id'], unique=False)
op.create_index(op.f('ix_products_stage'), 'products', ['stage'], unique=False)
op.create_index(op.f('ix_products_updated_at'), 'products', ['updated_at'], unique=False)
op.create_table('shops',
sa.Column('id', sa.Uuid(), nullable=False),
sa.Column('user_id', sa.Uuid(), nullable=True),
sa.Column('name', sa.String(length=128), nullable=False),
sa.Column('client_id_enc', sa.String(length=1024), nullable=False),
sa.Column('api_key_enc', sa.String(length=1024), nullable=False),
sa.Column('currency_code', sa.String(length=3), server_default='RUB', nullable=False),
sa.Column('status', sa.Enum('active', 'invalid', 'disabled', name='shopstatus', native_enum=False, length=16), nullable=False),
sa.Column('last_checked_at', sa.DateTime(timezone=True), nullable=True),
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('(CURRENT_TIMESTAMP)'), nullable=False),
sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('(CURRENT_TIMESTAMP)'), nullable=False),
sa.PrimaryKeyConstraint('id')
)
op.create_table('users',
sa.Column('id', sa.Uuid(), nullable=False),
sa.Column('username', sa.String(length=64), nullable=False),
sa.Column('password_hash', sa.String(length=255), nullable=False),
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('(CURRENT_TIMESTAMP)'), nullable=False),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('username')
)
op.create_table('product_assets',
sa.Column('id', sa.Uuid(), nullable=False),
sa.Column('product_id', sa.Uuid(), nullable=False),
sa.Column('group_key', sa.String(length=16), nullable=False),
sa.Column('variant_name', sa.String(length=128), nullable=True),
sa.Column('sort_order', sa.Integer(), nullable=False),
sa.Column('type', sa.String(length=8), nullable=False),
sa.Column('source_url', sa.Text(), nullable=False),
sa.Column('stored_url', sa.Text(), nullable=True),
sa.Column('status', sa.Enum('pending', 'downloading', 'uploaded', 'failed', name='assetstatus', native_enum=False, length=16), nullable=False),
sa.Column('dedupe_key', sa.String(length=512), nullable=True),
sa.Column('width', sa.Integer(), nullable=True),
sa.Column('height', sa.Integer(), nullable=True),
sa.Column('error', sa.Text(), nullable=True),
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('(CURRENT_TIMESTAMP)'), nullable=False),
sa.ForeignKeyConstraint(['product_id'], ['products.id'], ondelete='CASCADE'),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_product_assets_dedupe_key'), 'product_assets', ['dedupe_key'], unique=False)
op.create_index(op.f('ix_product_assets_product_id'), 'product_assets', ['product_id'], unique=False)
op.create_index(op.f('ix_product_assets_status'), 'product_assets', ['status'], unique=False)
op.create_table('publish_tasks',
sa.Column('id', sa.Uuid(), nullable=False),
sa.Column('product_id', sa.Uuid(), nullable=False),
sa.Column('shop_id', sa.Uuid(), nullable=False),
sa.Column('ozon_task_id', sa.BigInteger(), nullable=True),
sa.Column('status', sa.Enum('pending', 'processing', 'moderation', 'imported', 'failed', name='publishstatus', native_enum=False, length=16), nullable=False),
sa.Column('request_payload', sa.JSON(), nullable=True),
sa.Column('response', sa.JSON(), nullable=True),
sa.Column('errors', sa.JSON(), nullable=True),
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('(CURRENT_TIMESTAMP)'), nullable=False),
sa.Column('completed_at', sa.DateTime(timezone=True), nullable=True),
sa.ForeignKeyConstraint(['product_id'], ['products.id'], ondelete='CASCADE'),
sa.ForeignKeyConstraint(['shop_id'], ['shops.id'], ondelete='CASCADE'),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_publish_tasks_ozon_task_id'), 'publish_tasks', ['ozon_task_id'], unique=False)
op.create_index(op.f('ix_publish_tasks_product_id'), 'publish_tasks', ['product_id'], unique=False)
op.create_index(op.f('ix_publish_tasks_shop_id'), 'publish_tasks', ['shop_id'], unique=False)
op.create_index(op.f('ix_publish_tasks_status'), 'publish_tasks', ['status'], unique=False)
# ### end Alembic commands ###
def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_index(op.f('ix_publish_tasks_status'), table_name='publish_tasks')
op.drop_index(op.f('ix_publish_tasks_shop_id'), table_name='publish_tasks')
op.drop_index(op.f('ix_publish_tasks_product_id'), table_name='publish_tasks')
op.drop_index(op.f('ix_publish_tasks_ozon_task_id'), table_name='publish_tasks')
op.drop_table('publish_tasks')
op.drop_index(op.f('ix_product_assets_status'), table_name='product_assets')
op.drop_index(op.f('ix_product_assets_product_id'), table_name='product_assets')
op.drop_index(op.f('ix_product_assets_dedupe_key'), table_name='product_assets')
op.drop_table('product_assets')
op.drop_table('users')
op.drop_table('shops')
op.drop_index(op.f('ix_products_updated_at'), table_name='products')
op.drop_index(op.f('ix_products_stage'), table_name='products')
op.drop_index(op.f('ix_products_source_item_id'), table_name='products')
op.drop_index(op.f('ix_products_ozon_product_id'), table_name='products')
op.drop_index(op.f('ix_products_offer_id'), table_name='products')
op.drop_table('products')
op.drop_index(op.f('ix_category_tree_parent_id'), table_name='category_tree')
op.drop_table('category_tree')
op.drop_table('category_attributes')
op.drop_table('attribute_values')
# ### end Alembic commands ###