I have this issue with Alembic + FastAPI + PostgreSQL

SQL Alchemy Alembic generates migrations in reverse, downgrade creates the table and upgrade drops it, while the database is empty.

For example:

alembic revision --autogenerate -m "Testing 2"
INFO  [alembic.runtime.migration] Context impl PostgresqlImpl.
INFO  [alembic.runtime.migration] Will assume transactional DDL.
INFO  [alembic.autogenerate.compare] Detected removed index 'ix_Site_keyword' on 'Site'
INFO  [alembic.autogenerate.compare] Detected removed table 'Site'
  Generating /app/migrations/versions/1e3a0f40182c_testing_2.py ...  done

I’ve checked the file and I got this one:

"""Testing 2

Revision ID: 1e3a0f40182c
Revises: 928ab2a61fa7
Create Date: 2024-04-04 08:32:29.784316

"""
from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql

# revision identifiers, used by Alembic.
revision: str = '1e3a0f40182c'
down_revision: Union[str, None] = '928ab2a61fa7'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_index('ix_Site_keyword', table_name='Site')
    op.drop_table('Site')
    # ### end Alembic commands ###


def downgrade() -> None:
    # ### commands auto generated by Alembic - please adjust! ###
    op.create_table('Site',
    sa.Column('id', sa.UUID(), autoincrement=False, nullable=False),
    sa.Column('title', sa.VARCHAR(), autoincrement=False, nullable=True),
    sa.Column('keyword', sa.VARCHAR(), autoincrement=False, nullable=True),
    sa.Column('description', sa.TEXT(), autoincrement=False, nullable=True),
    sa.Column('is_active', sa.BOOLEAN(), autoincrement=False, nullable=True),
    sa.Column('created_at', postgresql.TIMESTAMP(), autoincrement=False, nullable=True),
    sa.Column('updated_at', postgresql.TIMESTAMP(), autoincrement=False, nullable=True),
    sa.Column('deleted_at', postgresql.TIMESTAMP(), autoincrement=False, nullable=True),
    sa.PrimaryKeyConstraint('id', name='Site_pkey')
    )
    op.create_index('ix_Site_keyword', 'Site', ['keyword'], unique=False)
    # ### end Alembic commands ###

Why do this one? If I switch the blocks (put upgrade block to downgrade block and vice-versa) If I run the next automigration, I got the all delete syntax in upgrade function… so, always I have to rewrite the code.

What’s going on here?