8

While maintaining a SQLAlchemy data model and utilizing alembic for version control, the following code change I made resulted in an empty revision:

some_column = Column(Boolean, nullable=False, default=False)

While previously it was:

some_column = Column(Boolean, nullable=False)

So adding a default value produces no changes in alembic, i.e. generates an empty revision. I tried other values offered by SQLAlchemy like false() and expression.false() instead of False, but the result is the same (empty alembic revision). Also tried server_default instead of default. The database in question is PostgreSQL.

By empty revision, of course I mean that alembic doesn't recognize any change being made in SQLAlchemy:

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    pass
    # ### end Alembic commands ###


def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    pass
    # ### end Alembic commands ###

Appreciate any help in this regard.

zarnoevic
  • 329
  • 3
  • 12

3 Answers3

9

To do this automatically you have to turn on a setting to detect server default changes.

In your env.py, for the context.configure calls (online and offline migrations, so in 2 places), add a compare_server_default=True kwarg.

It is probably safer to just put in the alter_column yourself as well as definitely use server_default because default is just for python-side setting of the default(which is ok but sounds like not what you want).

Quoted from https://alembic.sqlalchemy.org/en/latest/autogenerate.html#what-does-autogenerate-detect-and-what-does-it-not-detect

Autogenerate can optionally detect:

...

Change of server default. This will occur if you set the EnvironmentContext.configure.compare_server_default parameter to True, or to a custom callable function. This feature works well for simple cases but cannot always produce accurate results.

...

Charles L.
  • 5,795
  • 10
  • 40
  • 60
Ian Wilson
  • 6,223
  • 1
  • 16
  • 24
6

Just pass false() in server_default kwarg in Column.

ref: https://docs.sqlalchemy.org/en/14/core/sqlelement.html


from sqlalchemy.sql import false

some_column = Column(Boolean, server_default=false(), nullable=False)
Henry
  • 3,472
  • 2
  • 12
  • 36
Daniel Bailo
  • 127
  • 1
  • 6
0

Next part of code demonstrates how to define default value for new Boolean field in the table

from alembic import op
import sqlalchemy as sa

def upgrade():
    with op.batch_alter_table("jobs", schema=None) as batch_op:
        batch_op.add_column(
            sa.Column(
                "is_deleted",
                sa.Boolean(),
                server_default=sa.false(),
            )
        )
  • 1
    As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Apr 28 '23 at 18:17
  • This doesnt seem to work if you say are trying to do a bulk COPY from one table to another, but excluding a boolean column. – mike01010 Jul 11 '23 at 03:57