Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Alembic ignore specific tables

I'm using alembic to manage database migrations as per user defined sqlalchemy models. My challenge is that I'd like for alembic to ignore any creation, deletion, or changes to a specific set of tables.

Note: My Q is similar to this question Ignoring a model when using alembic autogenerate but is different in that I want to control alembic from outside the model definition.

Here's a sample table I want to ignore:

from sqlalchemy import MetaData
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base(metadata=MetaData())

class Ignore1(Base):
    """
    Signed in to the account...
    """
    __tablename__ = 'ignore_1'
    __table_args__ = {
        'info':{'skip_autogenerate':True}
        }
    id = Column(Integer, primary_key=True)
    foo = Column(String(20), nullable=True)

Example code (which does not solve my issue):
In alembic/env.py

# Ideally this is stored in my actual database, but for now, let's assume we have a list...
IGNORE_TABLES = ['ignore_1', 'ignore_2']

def include_object(object, name, type_, reflected, compare_to):
    """
    Should you include this table or not?
    """

    if type_ == 'table' and (name in IGNORE_TABLES or object.info.get("skip_autogenerate", False)):
        return False

    elif type_ == "column" and object.info.get("skip_autogenerate", False):
        return False

    return True

# Then add to config
context.configure(
    ...
    include_object=include_object,
    ...
    )
like image 868
Yaakov Bressler Avatar asked Dec 07 '20 14:12

Yaakov Bressler


People also ask

How does alembic Autogenerate work?

Alembic can view the status of the database and compare against the table metadata in the application, generating the “obvious” migrations based on a comparison. This is achieved using the --autogenerate option to the alembic revision command, which places so-called candidate migrations into our new migrations file.

What is alembic Version table?

Alembic generates a table in the project table space called alembic_version that keeps track of the unique ID of the last version file applied to the schema. During an update, Alembic uses this stored version ID to determine what if any follow on version files to process.

What is alembic revision?

Alembic provides for the creation, management, and invocation of change management scripts for a relational database, using SQLAlchemy as the underlying engine. This tutorial will provide a full introduction to the theory and usage of this tool.


1 Answers

I found a solution to my problem!

My error was in the instantiation of my context object in env.py

def run_migrations_offline():
    ...
    context.configure(
        url=url,
        target_metadata=target_metadata,
        include_object=include_object,
        literal_binds=True,
        dialect_opts={"paramstyle": "named"},
    )

    with context.begin_transaction():
        context.run_migrations()

I wasn't applying this change to context for online migrations:

def run_migrations_online():
    ...
    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,
            # THE FOLLOWING LINE WAS MISSING FROM MY ORIGINAL CODE
            include_object=include_object, # <----------------------- THIS!
        )
    ...

Hopefully anyone else encountering this issue and experiencing similar turmoil can read through my question & following solution and recognize that despair is but a small dumb tweak from salvation.

like image 72
Yaakov Bressler Avatar answered Oct 17 '22 23:10

Yaakov Bressler