Как удалить ограничение внешнего ключа в SQLAlchemy?

Я использую SQLAlchemy Migrate, чтобы отслеживать изменения базы данных, и у меня возникает проблема с удалением внешнего ключа. У меня две таблицы, t_new – новая таблица, а t_exists – существующая таблица. Мне нужно добавить t_new, а затем добавить внешний ключ к t_exists. Затем мне нужно иметь возможность отменить операцию (в которой у меня возникают проблемы).

t_new = sa.Table("new", meta.metadata, sa.Column("new_id", sa.types.Integer, primary_key=True) ) t_exists = sa.Table("exists", meta.metadata, sa.Column("exists_id", sa.types.Integer, primary_key=True), sa.Column( "new_id", sa.types.Integer, sa.ForeignKey("new.new_id", onupdate="CASCADE", ondelete="CASCADE"), nullable=False ) ) 

Это прекрасно работает:

 t_new.create() t_exists.c.new_id.create() 

Но это не так:

 t_exists.c.new_id.drop() t_new.drop() 

Попытка сбросить столбец внешнего ключа дает ошибку: 1025, «Ошибка при переименовании». \ My_db_name \ # sql-1b0_2e6 'to'. \ My_db_name \ exists '(errno: 150) "

Если я сделаю это с необработанным SQL, я могу удалить внешний ключ вручную, а затем удалить столбец, но мне не удалось выяснить, как удалить внешний ключ с помощью SQLAlchemy? Как удалить внешний ключ, а затем столбец?

4 Solutions collect form web for “Как удалить ограничение внешнего ключа в SQLAlchemy?”

Вы можете сделать это с помощью sqlalchemy.migrate.

Чтобы заставить его работать, мне пришлось создать ограничение внешнего ключа явно, а не неявно с Column ('fk', ForeignKey ('fk_table.field')):

Увы, вместо этого:

 p2 = Table('tablename', metadata, Column('id', Integer, primary_key=True), Column('fk', ForeignKey('fk_table.field')), mysql_engine='InnoDB', ) 

сделай это:

 p2 = Table('tablename', metadata, Column('id', Integer, primary_key=True), Column('fk', Integer, index=True), mysql_engine='InnoDB', ) ForeignKeyConstraint(columns=[p2.c.fk], refcolumns=[p3.c.id]).create() 

Затем процесс удаления выглядит следующим образом:

 def downgrade(migrate_engine): # First drop the constraint ForeignKeyConstraint(columns=[p2.c.fk], refcolumns=[p3.c.id]).drop() # Then drop the table p2.drop() 

Я смог выполнить это, создав отдельный экземпляр метаданных и используя Session.execute () для запуска raw SQL. В идеале, было бы решение, использующее исключительно sqlalchemy, поэтому мне не пришлось бы использовать решения, специфичные для MySQL. Но на данный момент я не знаю такого решения.

Я считаю, что вы можете добиться этого с помощью SQLAlchemy-Migrate. Обратите внимание, что ForeignKey находится в изолированном столбце. «ForeignKeyConstraint» находится на уровне таблицы и связывает столбцы вместе. Если вы посмотрите на объект ForeignKey в столбце, вы увидите, что он ссылается на ExternalKeyConstraint.

Я не смог бы проверить эту идею из-за того, что две базы данных, которые я использую MS SQL, не поддерживаются SqlAlchemy-Migrate, а sqlite не поддерживает «alter table» для ограничений. Я получил SQLAlchemy, чтобы попытаться удалить FK с помощью ограничения на ограничение ссылок на таблицу sqlite, чтобы она выглядела хорошо. YMMV.

Ну, вы можете достичь этого в sqlalchemy: просто drop() все ограничения перед тем, как вы drop() столбец (теоретически, вы можете иметь несколько ограничений):

 def drop_column(column): for fk in column.table.foreign_keys: if fk.column == column: print 'deleting fk ', fk fk.drop() column.drop() drop_column(t_exists.c.new_id) 
  • В SQLAlchemy возможен многоуровневый полиморфизм?
  • OperationalError: соединение MySQL недоступно
  • Почему не эта альтернатива устаревшей Factory.set_creation_function, работающей с nosetests?
  • Структура фляжных приложений
  • Почему эта флеш-админ-форма всегда не проходит проверку?
  • хранимые процедуры с sqlAlchemy
  • Использование другой схемы для той же декларативной базы в sqlalchemy
  • Объект 'Engine' не имеет атрибута 'drivername'
  • Python - лучший язык программирования в мире.