Alembic, Как изменить столбец ForeigenKey

Я использую Alembic 0.8.9, SQLAlchemy 1.1.4, и моя база данных - это база данных MySQL.
Я занимаюсь изменением таблицы и внешнего столбца:

В своей базе данных я переименовал таблицу «органы» в «цели». С использованием

from alembic import op

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

После этого я хочу обновить свой ForeignKey в другой таблице:

До

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

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

И после

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

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

Мне нужна помощь в написании скрипта миграции Alembic, чтобы это изменение отразилось в базе данных. Как изменить столбец ForeignKey?

Спасибо за помощь


person A-Palgy    schedule 19.06.2017    source источник
comment
Зачем переделывать? Это больше похоже на удаление organ_id, добавление target_id.   -  person sebastian    schedule 19.06.2017
comment
Если я уроню и добавлю, мои данные не будут потеряны? Я также переименовал таблицу «органы» в «цели».   -  person A-Palgy    schedule 19.06.2017
comment
Правильно - я не знал, что ваша настоящая цель - переименование чужой таблицы. В этом случае мой drop & create действительно не имеет смысла, я думаю   -  person sebastian    schedule 19.06.2017
comment
Спасибо, обновил вопрос   -  person A-Palgy    schedule 19.06.2017
comment
по этой теме по MySQL сбивает с толку. С другой стороны, внешние ключи, указывающие на переименованную таблицу, не обновляются автоматически. В таких случаях вы должны отбросить и воссоздать внешние ключи, чтобы они работали правильно., Но тестирование и этот отчет об ошибке, кажется, говорит об обратном. Если отчет об ошибке подтвердится, вам просто нужно op.alter_column('orders', 'organ_id', new_column_name='purpose_id') после переименования таблицы.   -  person Ilja Everilä    schedule 19.06.2017


Ответы (1)


Спасибо за полезные комментарии, которые побудили меня искать дополнительные сведения о внешних ключах SQL. Думаю, теперь я понял.
Этот ответ показал мне путь:
Как изменить ссылочное действие внешнего ключа? (поведение)

По сути, мне нужно было переименовать столбец (который содержит данные), удалить старый внешний ключ (ограничение?) И вместо этого создать новый.

Вот мой сценарий миграции:

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"])
person A-Palgy    schedule 19.06.2017