2012-12-07 8 views
6

Sto tentando di aggiungere una colonna di chiave primaria "id" a una tabella MySQL già esistente utilizzando alembic. Ho provato quanto segue ...Aggiunta di chiave primaria a una tabella MySQL esistente in alambicco

op.add_column('mytable', sa.Column('id', sa.Integer(), nullable=False)) 
op.alter_column('mytable', 'id', autoincrement=True, existing_type=sa.Integer(), existing_server_default=False, existing_nullable=False) 

ma ottenuto il seguente errore

sqlalchemy.exc.OperationalError: (OperationalError) (1075, 'Incorrect table definition; there can be only one auto column and it must be defined as a key') 'ALTER TABLE mytable CHANGE id id INTEGER NOT NULL AUTO_INCREMENT'() 

si presenta come l'istruzione SQL generata da alambicco non aggiungere PRIMARY KEY alla fine dell'istruzione ALTER. Potrei aver perso alcune impostazioni?

Grazie in anticipo!

risposta

16

Ho passato un po 'di tempo a scavare attraverso il codice sorgente alambicco, e questo non sembra essere supportato. È possibile specificare le chiavi primarie quando crea una tabella ma non quando si aggiungono colonne. In realtà, si verifica in particolare e non si lascerà:

# from alembic.operations.add_column, line 284 
for constraint in t.constraints: 
    if not isinstance(constraint, schema.PrimaryKeyConstraint): 
    self.impl.add_constraint(constraint) 

mi sono guardato intorno, e l'aggiunta di una chiave primaria per una tabella esistente può causare un comportamento non specificato - le chiavi primarie non dovrebbero essere nullo, così il tuo motore potrebbe o meno creare chiavi primarie per le righe esistenti. Vedere questa discussione SO per ulteriori informazioni: Insert auto increment primary key to existing table

Vorrei solo eseguire direttamente la query di modifica e creare chiavi primarie se necessario.

op.execute("ALTER TABLE mytable ADD id INT PRIMARY KEY AUTO_INCREMENT;") 

Se davvero bisogno di compatibilità cross-motore, il grande martello sarebbe quello di (1) creare una nuova tabella identico a quello vecchio con una chiave primaria, (2) la migrazione di tutti i dati, (3) elimina la vecchia tabella e (4) rinomina la nuova tabella.

Spero che questo aiuti.

Problemi correlati