Search code examples
databasesqlalchemyalembic

Change sa.Column nullable property with Alembic in Batch mode


I have a database upgrade migration I want to apply to Database column:

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    with op.batch_alter_table('details') as batch_op:
        batch_op.alter_column('details', 'non_essential_cookies',
                              existing_type=sa.BOOLEAN(),
                              nullable=False)
    # ### end Alembic commands ###

I am implementing batch mode sice ALTER is unsupported and previously I received this error : sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) near "ALTER":. However, I hoped batch mode would work but now instead I receive the new error:

TypeError: <flask_script.commands.Command object at 0x1149bb278>: alter_column() got multiple values for argument 'nullable'.

I only have one tuple in the table and the relevant attribute is not NULL so the database migration is valid. I just don't understand why there are multiple values


Solution

  • From docs:

    The method is used as a context manager, which returns an instance of BatchOperations; this object is the same as Operations except that table names and schema names are omitted.

    Key point here being that you don’t have to provide the table name when calling ops on the BatchOperations instance.

    The signature for alter_column is:

    alter_column(table_name, column_name, nullable=None, server_default=False, new_column_name=None, type_=None, existing_type=None, existing_server_default=False, existing_nullable=None, schema=None, **kw)
    

    So from your code:

    with op.batch_alter_table('details') as batch_op:
            batch_op.alter_column('details', 'non_essential_cookies',
                                  existing_type=sa.BOOLEAN(),
                                  nullable=False)
    

    'details' is being passed to column_name, and 'non_essential_cookies' is getting passed to nullable as a positional argument. The issue is caused later when you specify the value of nullable again with the keyword arg,nullable=False.