web-dev-qa-db-ja.com

Alembic:IntegrityError: "null値を含まない列を追加すると、列にnull値が含まれます"

既存のテーブルに列を追加しています。この新しい列はnullable=False

op.add_column('mytable', sa.Column('mycolumn', sa.String(), nullable=False))

移行を実行すると、次のエラーが表示されます。

sqlalchemy.exc.IntegrityError: column "mycolumn" contains null values
41
Ron

それは、既存のデータにその新しい列の値がない、つまりnullであるためです。したがって、上記のエラーが発生します。 NULL不可の列を追加する場合、既存のデータに与える値を決定する必要があります


さて、既存のデータには、この新しい列の「lorem ipsum」が必要です。しかし、どうすればいいですか?列がまだないため、更新できません。

_server_default_ argを使用します。

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

しかし、しかし、私はそれがデフォルト値を持ちたくない

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)
_
68
Ron

@Ronの答えに代わるものは、反対のことを行い、データを変更することですbefore制約を追加します:

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)

私にとってはよりクリーンで強力なようですが、あなたはSQLを書いています:-)。

27
Antoine Lizée

その列のデータベースに既存の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)       
5
Arjunsingh