Problem
I'm using Alembic autogenerate to migrate some model changes. I run alembic revision/upgrade once and it properly creates my table and adds an alembic_version table to my database. When I go to run the revision/upgrade command again, it tries to recreate the table despite no changes being made to the model
alembic.command.revision(cfg, autogenerate=True)
INFO [alembic.runtime.migration] Context impl PostgresqlImpl.
INFO [alembic.runtime.migration] Will assume transactional DDL.
INFO [alembic.autogenerate.compare] Detected added table 'alias.alias'
As you can see here it's attempting to add the table alias.alias even though it already exists in my database and was created by Alembic in the first revision/upgrade command.
Predictably, when I attempt to run the second upgrade I get the error
psycopg2.errors.DuplicateTable: relation "alias" already exists
Current setup
env.py
import sys
import os
sys.path.insert(0, '/tmp/')
from logging.config import fileConfig
from sqlalchemy import engine_from_config
from sqlalchemy import pool
from alembic import context
from models.Base import Base
from models import Alias
config = context.config
fileConfig(config.config_file_name)
target_metadata = Base.metadata
def run_migrations_offline():
"""Run migrations in 'offline' mode.
This configures the context with just a URL
and not an Engine, though an Engine is acceptable
here as well. By skipping the Engine creation
we don't even need a DBAPI to be available.
Calls to context.execute() here emit the given string to the
script output.
"""
url = config.get_main_option("sqlalchemy.url")
context.configure(
url=url,
target_metadata=target_metadata,
literal_binds=True,
dialect_opts={"paramstyle": "named"},
)
with context.begin_transaction():
context.run_migrations()
def run_migrations_online():
"""Run migrations in 'online' mode.
In this scenario we need to create an Engine
and associate a connection with the context.
"""
connectable = engine_from_config(
config.get_section(config.config_ini_section),
prefix="sqlalchemy.",
poolclass=pool.NullPool,
)
with connectable.connect() as connection:
context.configure(
connection=connection, target_metadata=target_metadata
)
with context.begin_transaction():
context.run_migrations()
if context.is_offline_mode():
run_migrations_offline()
else:
run_migrations_online()
Alias.py
from sqlalchemy import Column, Integer, String
from models.Base import Base
class Alias(Base):
__tablename__ = 'alias'
__table_args__ = {'schema': 'alias'}
id = Column(Integer, primary_key=True)
chart_config = Column(String)
name = Column(String, nullable=False, unique=True)
display_name = Column(String)
datasets = Column(String)
Base.py
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
Expected outcome
How do I get alembic to detect that the alias.alias table already exists? It should autogenerate an empty revision. The model Alias.py is completely static during my 2 runs of revision/upgrade