Alembic:IntegrityError:添加非可空列时"列包含空值"

Ron*_*Ron 42 python sqlalchemy alembic

我正在向现有表添加列.这个新专栏是nullable=False.

op.add_column('mytable', sa.Column('mycolumn', sa.String(), nullable=False))
Run Code Online (Sandbox Code Playgroud)

当我运行迁移时,它会抱怨:

sqlalchemy.exc.IntegrityError: column "mycolumn" contains null values
Run Code Online (Sandbox Code Playgroud)

Ron*_*Ron 72

这是因为您的现有数据对该新列没有任何价值,即null.从而导致所述错误.添加不可为空的列时,必须确定为现有数据提供的值


好吧,现在的数据应该只有这个新专栏的"lorem ipsum".但是我该怎么办呢?我无法更新,因为该列还没有.

使用server_defaultarg:

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

但是,我不希望它具有默认值

之后再使用它 op.alter_column('mytable', 'mycolumn', server_default=None)

例如你的upgrade()功能是:

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)
Run Code Online (Sandbox Code Playgroud)

  • @Steve使用''True'和''False'而不是'True`和'False` (16认同)
  • 还必须注意,所有值都应作为字符串传递(即使是整数也要传递!),因为server_default是专门在“ CREATE TABLE”语句的“ DEFAULT”部分中指定的SQL文本。就我而言,我必须指定`op.add_column(“ project”,sa.Column(“ tenant_id”,sa.Integer(),nullable = False,server_default =“ 1”),)`以使其正常工作(我id是整数) (2认同)
  • 如果为 `bool` 类型使用默认值,请使用 `sa.sql.expression.false()` 或 `sa.sql.expression.true()` 如下: `op.add_column('table', sa.Column( 'col_name', sa.Boolean(), nullable=False, server_default=sa.sql.expression.false()))` (2认同)

Ant*_*zée 28

@ Ron的答案的另一种选择是反过来,并添加约束之前修改数据:

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)
Run Code Online (Sandbox Code Playgroud)

对我来说似乎更清洁,更强大,但你正在编写SQL :-).

  • 使用MySQL后端时,最后一行应该是op.alter_column('my_table','my_column',existing_type = sa.String(),nullable = False),否则你会得到一个alembic.util.exc.CommandError(更多关于[这里](http://alembic.zzzcomputing.com/en/latest/ops.html#alembic.operations.Operations.alter_column)) (2认同)

Arj*_*ngh 5

它正确地告诉您,数据库中该列存在(或将存在)现有NULL值。答案是在更改列定义之前编辑迁移文件以更新列:

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)       
Run Code Online (Sandbox Code Playgroud)

  • 与其他答案相比,这是一种更干净的方法。 (2认同)