Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Alembic, How to alter a ForeigenKey Column

I'm using Alembic 0.8.9, SQLAlchemy 1.1.4 and my database is a MySQL database.
I'm in the process of altering a table and a Foreign column:

In my database, I'm renaming 'organs' table to be named 'purposes'. Using

from alembic import op

def upgrade():
    op.rename_table('organs', 'purposes')

After that, I want to update my ForeignKey In a differnt table:

Before

class Order(DeclarativeBase):
    __tablename__ = 'orders'
    id = Column(Integer, autoincrement=True, primary_key=True)

    organ_id = Column(Integer, ForeignKey('organs.id'))

And After

class Order(DeclarativeBase):
    __tablename__ = 'orders'
    id = Column(Integer, autoincrement=True, primary_key=True)

    purpose_id = Column(Integer, ForeignKey('purposes.id'))

I need help writing an Alembic migrate script for this change to be reflected in the database. How do I alter a ForeignKey column?

Thanks for the help

like image 891
A-Palgy Avatar asked Jun 19 '17 12:06

A-Palgy


People also ask

How do I change a column to a foreign key?

How do I change an existing column from bit to a foreign key ( int )? But now I want the NEW_B to reference column ID (int) of table ATTACHMENT (want to keep the name NEW_B , also allow NULLs ). First alter table and set the column type to int, then add a foreign key constraint.

Can foreign key be changed?

You can modify the foreign key side of a relationship in SQL Server by using SQL Server Management Studio or Transact-SQL. Modifying a table's foreign key changes which columns are related to columns in the primary key table.

Can we add foreign key with ALTER TABLE?

We can add a FOREIGN KEY constraint to a column of an existing MySQL table with the help of ALTER TABLE statement.


1 Answers

Thanks for the helpful comments that led my to search a bit more about SQL Foreign Keys. I think I got it now.
This answer showed me the way:
How to change the foreign key referential action? (behavior)

Basically what I needed to do was rename the column (which holds the data), drop the old Foreign Key (constraint?) and create a new one instead.

Here is my migration script:

from alembic import op
import sqlalchemy as sa


def upgrade():
    op.rename_table('organs', 'purposes')
    op.alter_column('orders', 'organ_id', new_column_name='purpose_id', existing_type=sa.Integer)
    op.drop_constraint(constraint_name="orders_ibfk_2", table_name="orders", type_="foreignkey")
    op.create_foreign_key(
        constraint_name="orders_ibfk_2",
        source_table="orders",
        referent_table="purposes",
        local_cols=["purpose_id"],
        remote_cols=["id"])


def downgrade():
    op.rename_table('purposes', 'organs')
    op.alter_column('orders', 'purpose_id', new_column_name='organ_id', existing_type=sa.Integer)
    op.drop_constraint(constraint_name="orders_ibfk_2", table_name="orders", type_="foreignkey")
    op.create_foreign_key(
        constraint_name="orders_ibfk_2",
        source_table="orders",
        referent_table="organs",
        local_cols=["organ_id"],
        remote_cols=["id"])
like image 84
A-Palgy Avatar answered Oct 05 '22 23:10

A-Palgy