Alembic: IntegrityError: “column contains null values” when adding non-nullable column

▼魔方 西西 提交于 2019-12-02 19:01:42
Ron

It is because your existing data have no value on that new column, i.e. null. Thus causing said error. When adding a non-nullable column, you must decide what value to give to already-existing data


Alright, existing data should just have "lorem ipsum" for this new column then. But how do I do it? I can't UPDATE because the column is not there yet.

Use the server_default arg:

op.add_column('mytable', sa.Column(
    'mycolumn', 
    sa.String(), 
    nullable=False, 
    server_default='lorem ipsum', #  <---  add this
))

But, but, I don't want it to have default value

Drop it afterwards using op.alter_column('mytable', 'mycolumn', server_default=None)

E.g. your upgrade() function would be:

def upgrade():
    op.add_column('mytable', sa.Column('mycolumn', sa.String(), nullable=False, server_default='lorem ipsum'))
    op.alter_column('mytable', 'mycolumn', server_default=None)

An alternative to @Ron's answer is to do the contrary, and modify the data before adding the constraint:

def upgrade():
    op.add_column('my_table', sa.Column('my_column', sa.String()))
    op.execute('UPDATE my_table SET my_column=my_other_column')
    op.alter_column('my_table', 'my_column', nullable=False)

Seems cleaner and more powerful to me, but you're writing SQL :-).

It tells you - rightly - that there are (or will be) existing NULL values in the database for that column. The answer is to edit the migration file to update the column before changing the column definition:

from sqlalchemy.sql import table, column

def upgrade():
    op.add_column('role', sa.Column('role_name', sa.String(length=30), nullable=True))
    role = table('role', column('role_name'))       
    op.execute(role.update().values(role_name=''))       
    op.alter_column('role', 'role_name', nullable=False)       
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!