Изменить первичный ключ в Alembic?
Я прочитал документы, но я нигде не могу найти инструкции. Я попытался сбросить старый ключ и добавить новый, но это вызывает ошибки:
op.drop_constraint('PRIMARY', 'some_table', type_='primary')
op.create_primary_key('PRIMARY', 'some_table', ['col1', 'col2'])
sqlalchemy.exc.OperationalError: (OperationalError) (1025, "Error on rename of ... (errno: 150 - Foreign key constraint is incorrectly formed)") 'ALTER TABLE some_table DROP PRIMARY KEY ' ()
Что я делаю неправильно?
Ответы
Ответ 1
Я столкнулся с этим вопросом, ища примерную миграцию. Итак, вот моя полная миграция, которая снижает ограничение PK и вместо этого добавляет новую AUTO INCREMENT
PK:
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects.mysql import INTEGER
def upgrade():
op.drop_constraint('PRIMARY', 'similar_orders', type_='primary')
op.execute("ALTER TABLE similar_orders ADD COLUMN id INTEGER UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT")
def downgrade():
op.drop_column('similar_orders', 'id')
op.create_primary_key("similar_orders_pk", "similar_orders", ["order_id", ])
Изменение столбца PK в столбце не работает в alembic, вместо этого используйте drop_constraint, см. здесь. Надеюсь, это поможет!
Ответ 2
Я тоже был в той же ситуации: изменил первичный ключ. В моем случае мне пришлось изменить тип первичного ключа из целого в строку.
Первичный ключ также имел отношение внешнего ключа к другой таблице. Ранняя миграция alembic создала ограничение внешнего ключа следующим образом:
#!/usr/bin/python3
from alembic import op
import sqlalchemy as sa
def upgrade():
op.create_table('user',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('name', sa.String(length=100), nullable=False),
sa.Column('username', sa.String(length=100), nullable=False),
sa.PrimaryKeyConstraint('id', name=op.f('pk_user')),
sa.UniqueConstraint('username', name=op.f('uq_user_username'))
)
op.create_table('role',
sa.Column('id', sa.Integer, primary_key=True),
sa.Column('name', sa.String(100)),
sa.Column('description', sa.String(255)),
sa.PrimaryKeyConstraint('id', name=op.f('pk_role'))
)
op.create_table('roles_users',
sa.Column('user_id', sa.Integer, nullable=True),
sa.Column('role_id', sa.Integer, nullable=True),
sa.ForeignKeyConstraint(['user_id'], ['user.id'],
name=op.f('fk_roles_user_user_id_user')),
sa.ForeignKeyConstraint(['role_id'], ['role.id'],
name=op.f('fk_roles_user_role_id_role'))
)
Теперь при изменении типа первичного ключа таблицы user
от Integer
до String
мне пришлось сделать следующее:
from alembic import op
import sqlalchemy as sa
def upgrade():
# Drop primary key constraint. Note the CASCASE clause - this deletes the foreign key constraint.
op.execute('ALTER TABLE user DROP CONSTRAINT pk_user CASCADE')
# Change primary key type
op.alter_column('user', 'id', existing_type=sa.Integer, type_=sa.VARCHAR(length=25))
op.alter_column('roles_users', 'user_id', existing_type=sa.Integer, type_=sa.VARCHAR(length=25))
# Re-create the primary key constraint
op.create_primary_key('pk_user', 'user', ['id'])
# Re-create the foreign key constraint
op.create_foreign_key('fk_roles_user_user_id_user', 'roles_users', 'user', ['user_id'], ['id'], ondelete='CASCADE')
Версия фляжки: 0.12.1
Alembic версия: 0.9.1
Версия Python: 3.4.4
Надеемся, что эта информация поможет кому-то столкнуться с подобной проблемой.