10

Я создал приложение python, которое использует elixir/sqlalchemy для хранения данных. Второй выпуск программного обеспечения требует обновления любых файлов, созданных в предыдущей версии, для добавления/удаления таблиц и столбцов.Обновление схемы базы данных sqlite с sqlalchemy и elixir

Мой вопрос: как я могу это достичь? Я знаю sqlalchemy-migrate, но должен сказать, что я нахожу это запутанным. В нем не упоминается, что происходит с существующими данными. Более того, sqlite имеет reduced ALTER TABLE support, так что будет мигрировать, если я попытаюсь удалить столбец? Существуют ли другие способы использования миграции?

ответ

7

Что вы говорите, это хорошо известная и довольно сложная проблема. Он известен как миграция базы данных. В каждом хорошем проекте есть политика, которая описывает, как применять схему базы данных и мутации данных для перехода от одной версии продукта к другой.

Многие фреймворки, такие как Django или Ruby on Rails, имеют систему миграции, встроенную или доступную как плагин. В вашем случае с SQLAlchemy есть несколько вариантов:

  1. Не используйте систему. Просто напишите /tmp/migrate.sql руками, запишите инструкции ALTER/DROP/CREATE, скрестите пальцы и примените их к базе SQLite. Это, как правило, плохая идея, поскольку она подвержена ошибкам, но выбор зависит от вас. Отсутствие полнофункционального оператора ALTER TABLE можно было бы создать, создав новый столбец с требуемыми свойствами с временным именем, скопировав все данные из исходного столбца на него, удалив исходный столбец и переименовав новый столбец в исходное имя. Та же методика может использоваться на уровне таблицы.
  2. Используйте некоторую стороннюю миграционную систему, такую ​​как liquibase. Liquibase классная, хорошо спроектированная и мощная, за исключением одного недостатка. Это действительно багги. Я попробовал это для SQLite (и да для SQLAlchemy, но на самом деле это неважно), и он не смог выполнить некоторые довольно простые вещи. Я googled для проблем и обнаружил, что они известные ошибки.
  3. Используйте SQLAlchemy-migrate, о котором вы упоминали. Он не так силен, как ROR-миграции, на которые он был вдохновлен, ни он не столь же мощный, как ликбаза, но он работает. Ограничение SQLite можно было бы работать одинаково.

И вы спросили, что произойдет с SQLAlchemy-migrate, если вы попытаетесь удалить столбец. Ну, он удалит столбец и поэтому удалит все данные, которые были в нем. Остальные столбцы в таблице останутся нетронутыми.

0

Что вас смущает в sqlalchemy-migrate? У него есть опции --preview_sql и --preview_py для предварительного просмотра того, что он собирается делать. В общем случае невозможно выполнить правильную миграцию для любого возможного случая, но вы можете модифицировать сгенерированный сценарий миграции для удовлетворения ваших потребностей. Легко получить ответы на остальные, попробовав это.

5

Более поздняя альтернатива sqlalchemy-migrate - alembic, написанная автором самой SQLAlchemy. Хотя последний («тот же автор») выглядит сильным аргументом, недостатком может быть то, что он не поддерживает таблицу ALTERATION с SQLite, то есть он не имеет встроенных обходных путей для поддержки SQLite без поддержки ALTER. (Можно утверждать, что это выходит за рамки и вполне может быть решено специализированным пакетом python или расширением SQLite.)