Версии программного обеспечения: alembic 1.0.5, SQLAlchemy 1.2.14, MySQL 5.7, Python 3.6.7
Я пытаюсь использовать alembic для поддержания схемы базы данных MySQL и представления Python ORM в действии.
Проблема, с которой я сталкиваюсь, заключается в том, что при миграциях всегда возникают избыточные отбрасывания и создаются команды для внешних ключей.Кажется, что autogenerate видит что-то отличное, но на самом деле они одинаковы.
При повторных вызовах команд :
alembic revision --autogenerate
alembic upgrade head
... будетпроизвести такое же падение и создать команды.
Запись в стандартный вывод показывает что-то вроде (например):
INFO [alembic.autogenerate.compare] Detected removed foreign key (t1_id)(id) on table table_two
INFO [alembic.autogenerate.compare] Detected added foreign key (t1_id)(id) on table test_fktdb.table_two
и сценарий миграции имеет:
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_constraint('fk_table1', 'table_two', type_='foreignkey')
op.create_foreign_key('fk_table1', 'table_two', 'table_one', ['t1_id'], ['id'], source_schema='test_fktdb', referent_schema='test_fktdb')
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_constraint('fk_table1', 'table_two', schema='test_fktdb', type_='foreignkey')
op.create_foreign_key('fk_table1', 'table_two', 'table_one', ['t1_id'], ['id'])
# ### end Alembic commands ###
Эта проблема может быть повторена, и я сделал минимальный пример (tar.gz на https://github.com/sqlalchemy/alembic/files/2625781/FK_test.tar.gz). ORM в примере выглядит примерно так:
[...import and bobs...]
class TableOne(Base):
"""Class representing a table with an id."""
__tablename__ = "table_one"
id = Column(UNSIGNED_INTEGER, nullable=False, autoincrement=True, primary_key=True)
__table_args__ = (
dict(mysql_engine='InnoDB'),
)
class TableTwo(Base):
"""A table representing records with a foreign key link to table one."""
__tablename__ = "table_two"
id = Column(UNSIGNED_INTEGER, nullable=False, autoincrement=True, primary_key=True)
t1_id = Column(UNSIGNED_INTEGER, nullable=False)
__table_args__ = (
ForeignKeyConstraint(["t1_id"], ["test_fktdb.table_one.id"], name="fk_table1"),
dict(mysql_engine='InnoDB'),
)
Есть ли что-нибудь, чтоМожно ли сделать так, чтобы alembic «видел» FK в базе данных как те же, что и в ORM? Применяя некоторую конфигурацию через env.py
, например?
Я искал этопроблема и обнаружил некоторые старые проблемы в GitHub (см. [1], [2], [3]). Проблемы, которые имеют решения, кажется, имеют дело с базами данных postgres и общедоступной схемой. Я не уверен, что это относится кв этом случае, поскольку я использую MySQL, соответствующая документация для общедоступных схем postgres находится здесь: https://docs.sqlalchemy.org/en/latest/dialects/postgresql.html#remote-schema-table-introspection-and-postgresql-search-path
Я добавил свою собственную проблему в репозиторий GitHub alembic: https://github.com/sqlalchemy/alembic/issues/519
Закрытые проблемы в системе отслеживания проблем, которые показывают похожие симптомы, но чейне применяются (насколько я вижу):
[1] https://github.com/sqlalchemy/alembic/issues/444
[2] https://github.com/sqlalchemy/alembic/issues/398
[3] https://github.com/sqlalchemy/alembic/issues/293