"""add market_places table and nav_tops.market_id Revision ID: b2c3d4e5f6a7 Revises: a1b2c3d4e5f6 Create Date: 2026-02-10 """ from alembic import op import sqlalchemy as sa from sqlalchemy import text revision = 'b2c3d4e5f6a7' down_revision = 'a1b2c3d4e5f6' branch_labels = None depends_on = None def upgrade() -> None: # 1. Create market_places table op.create_table( 'market_places', sa.Column('id', sa.Integer(), autoincrement=True, nullable=False), sa.Column('post_id', sa.Integer(), nullable=False), sa.Column('name', sa.String(255), nullable=False), sa.Column('slug', sa.String(255), nullable=False), sa.Column('description', sa.Text(), nullable=True), sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False), sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False), sa.Column('deleted_at', sa.DateTime(timezone=True), nullable=True), sa.ForeignKeyConstraint(['post_id'], ['posts.id'], ondelete='CASCADE'), sa.PrimaryKeyConstraint('id'), ) op.create_index('ix_market_places_post_id', 'market_places', ['post_id']) op.create_index( 'ux_market_places_slug_active', 'market_places', [sa.text('lower(slug)')], unique=True, postgresql_where=sa.text('deleted_at IS NULL'), ) # 2. Add market_id column to nav_tops op.add_column( 'nav_tops', sa.Column('market_id', sa.Integer(), nullable=True), ) op.create_foreign_key( 'fk_nav_tops_market_id', 'nav_tops', 'market_places', ['market_id'], ['id'], ondelete='SET NULL', ) op.create_index('ix_nav_tops_market_id', 'nav_tops', ['market_id']) # 3. Backfill: create default MarketPlace for the 'market' page conn = op.get_bind() # Find the market page result = conn.execute(text(""" SELECT id FROM posts WHERE slug = 'market' AND is_page = true AND deleted_at IS NULL LIMIT 1 """)) row = result.fetchone() if row: post_id = row[0] # Insert the default market conn.execute(text(""" INSERT INTO market_places (post_id, name, slug, created_at, updated_at) VALUES (:post_id, 'Suma Market', 'suma-market', now(), now()) """), {"post_id": post_id}) # Get the new market_places id market_row = conn.execute(text(""" SELECT id FROM market_places WHERE slug = 'suma-market' AND deleted_at IS NULL LIMIT 1 """)).fetchone() if market_row: market_id = market_row[0] # Assign all active nav_tops to this market conn.execute(text(""" UPDATE nav_tops SET market_id = :market_id WHERE deleted_at IS NULL """), {"market_id": market_id}) def downgrade() -> None: op.drop_index('ix_nav_tops_market_id', table_name='nav_tops') op.drop_constraint('fk_nav_tops_market_id', 'nav_tops', type_='foreignkey') op.drop_column('nav_tops', 'market_id') op.drop_index('ux_market_places_slug_active', table_name='market_places') op.drop_index('ix_market_places_post_id', table_name='market_places') op.drop_table('market_places')