web-dev-qa-db-de.com

Alembic: IntegrityError: "Spalte enthält Nullwerte" beim Hinzufügen einer nicht-nullfähigen Spalte

Ich füge einer vorhandenen Tabelle eine Spalte hinzu. Diese neue Spalte lautet nullable=False.

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

Wenn ich die Migration durchführe, beschwert sie sich:

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

Dies liegt daran, dass Ihre vorhandenen Daten für diese neue Spalte keinen Wert haben, d. H. null. Dadurch wird der Fehler verursacht. Wenn Sie eine nicht-nullfähige Spalte hinzufügen, müssen Sie entscheiden, welchen Wert Sie bereits vorhandenen Daten zuweisen möchten


Okay, vorhandene Daten sollten dann nur "lorem ipsum" für diese neue Spalte haben. Aber wie mache ich das? Ich kann kein Update durchführen, da die Spalte noch nicht vorhanden ist.

Verwenden Sie den server_default arg:

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

Aber ich möchte nicht, dass es einen Standardwert hat

Hinterlassen Sie es mit op.alter_column('mytable', 'mycolumn', server_default=None)

Z.B. Ihre upgrade()-Funktion wäre:

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)
53
Ron

Eine Alternative zu @ Rons Antwort ist, das Gegenteil zu tun und die Daten vor Hinzufügen der Einschränkung zu ändern:

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)

Scheint mir klarer und mächtiger zu sein, aber Sie schreiben SQL :-).

22
Antoine Lizée

Es sagt Ihnen - zu Recht -, dass in der Datenbank für diese Spalte NULL-Werte vorhanden sind oder sein werden. Die Antwort besteht darin, die Migrationsdatei so zu bearbeiten, dass die Spalte aktualisiert wird, bevor die Spaltendefinition geändert wird:

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)       
0
Arjunsingh