Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I ignore certain schemas with alembic --autogenerate

I have a library that's part of a bigger project. The library uses its own schema in a (PostgreSQL) database shared with the larger project.

I want to use alembic revision --autogenerate to only generate migrations for the library's schema and ignore changes to the tables in the main/default schema. Is there any option for doing this?

FWIW, I've tried the include_schemas=False parameter to context.configure in env.py, but it doesn't seem to do anything.

like image 291
Oin Avatar asked Feb 11 '16 14:02

Oin


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.

How do I get rid of migration in alembic?

There's currently no command to delete migrations from your versions directory, so if you want to completely wipe away all trace of your bad migration, you'll need to delete the version file (like 4c009570237e_add_widget_table.py ) manually.

What does alembic stamp head do?

The head will automatically revert to the most recent remaining migration. Using stamp will set the db version value to the specified revision; not alter the head revision number. Based on your question, the original answer will resolve your issue.

How does alembic work in Python?

alembic - this directory lives within your application's source tree and is the home of the migration environment. It can be named anything, and a project that uses multiple databases may even have more than one. env.py - This is a Python script that is run whenever the alembic migration tool is invoked.


3 Answers

Based on Oin response, finally a method which ignores tables while running db revision --autogenerate

In alembic/env.py or migrations/env.py:

def include_object(object, name, type_, reflected, compare_to):
    if (type_ == "table" and object.schema == "exclude_from_migrations"):
        return False
    else:
       return True

In alembic/env.py or migrations/env.py:

def run_migrations_online():
   ....
   context.configure(connection=connection,
                  target_metadata=target_metadata,
                  include_object = include_object,
                  process_revision_directives=process_revision_directives,
                  **current_app.extensions['migrate'].configure_args)
   ...

Now in the tables that you want to ignore:

class MyClass(db.Model):
__tablename__='my_class'
__table_args__ = {"schema": "exclude_from_migrations"}
like image 147
christianAV Avatar answered Oct 18 '22 08:10

christianAV


It seems I can use include_object in conjunction with include_schemas

In alembic/env.py:

def include_object(object, name, type_, reflected, compare_to):
    if type_ == 'table' and object.schema != MY_SCHEMA:
        return False

    return True

...
context.configure(..., include_object=include_object, ...)
like image 23
Oin Avatar answered Oct 18 '22 09:10

Oin


Try use include_name: https://alembic.sqlalchemy.org/en/latest/api/runtime.html#alembic.runtime.environment.EnvironmentContext.configure.params.include_name

This is a new hook added in alembic==1.5, and is the recommended way to filter out schemas during autogenerate:

For the use case of omitting specific schemas from a target database when EnvironmentContext.configure.include_schemas is set to True, the schema attribute can be checked for each Table object passed to the hook, however it is much more efficient to filter on schemas before reflection of objects takes place using the EnvironmentContext.configure.include_name hook.

Related discussion: https://github.com/sqlalchemy/alembic/issues/650

like image 25
Alan Avatar answered Oct 18 '22 10:10

Alan