Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding primary key to existing MySQL table in alembic

I am trying to add an 'id' primary key column to an already existing MySQL table using alembic. I tried the following...

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) 

but got the following error

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' ()

looks like the sql statement generated by alembic did not add PRIMARY KEY at the end of the alter statement. Could I have missed some settings?

Thanks in advance!

like image 266
minovsky Avatar asked Dec 07 '12 03:12

minovsky


People also ask

How do I add a primary key to an existing table in MySQL?

When the table does not have a primary key, this statement is used to add the primary key to the column of an existing table. Following are the syntax of the ALTER TABLE statement to create a primary key in MySQL: ALTER TABLE table_name ADD PRIMARY KEY(column_list);

Can you add a primary key to an existing table?

Because a table can have only one primary key, you cannot add a primary key to a table that already has a primary key defined. To change the primary key of a table, delete the existing key using a DROP clause in an ALTER TABLE statement and add the new primary key.

How do I add a primary key without dropping the table?

How do I add a primary key without dropping the table? However, you can only use the ALTER TABLE statement to create a primary key on column(s) that are already defined as NOT NULL. If the column(s) allow NULL values, you will not be able to add the primary key without dropping and recreating the table.

How do you add a primary key in a table using alter?

Now, to create a PRIMARY KEY constraint on any column when the table already exists (NO EARLIER PRIMARY KEY DEFINED), use the following SQL Syntax: ALTER TABLE [Table_Name] ADD PRIMARY KEY (ID); Query: ALTER TABLE Employee ADD PRIMARY KEY (Phone_No);


1 Answers

I spent some time digging through the alembic source code, and this doesn't seem to be supported. You can specify primary keys when creating a table, but not when adding columns. In fact, it specifically checks and won't let you (link to source):

# from alembic.operations.toimpl.add_column, line 132
for constraint in t.constraints:
    if not isinstance(constraint, sa_schema.PrimaryKeyConstraint):
        operations.impl.add_constraint(constraint)

I looked around, and adding a primary key to an existing table may result in unspecified behavior - primary keys aren't supposed to be null, so your engine may or may not create primary keys for existing rows. See this SO discussion for more info: Insert auto increment primary key to existing table

I'd just run the alter query directly, and create primary keys if you need to.

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

If you really need cross-engine compatibility, the big hammer would be to (1) create a new table identical to the old one with a primary key, (2) migrate all your data, (3)delete the old table and (4) rename the new table.

Hope that helps.

like image 198
Rachel Sanders Avatar answered Sep 29 '22 11:09

Rachel Sanders