11

我创建了一个使用 elixir/sqlalchemy 存储数据的 python 应用程序。该软件的第二个版本需要更新在先前版本中创建的任何文件,以便添加/删除表和列。

我的问题是:我怎样才能做到这一点?我知道sqlalchemy-migrate,但我必须说我觉得它令人困惑。它没有提到现有数据会发生什么。此外,sqlite减少了 ALTER TABLE 支持,那么如果我尝试删除列,迁移会做什么?还有其他使用迁移的方法吗?

4

3 回答 3

8

你所说的是一个众所周知且相当复杂的问题。它被称为数据库迁移。每个好的项目都有一些策略来描述应该如何应用数据库模式和数据突变以从一个产品版本升级到另一个产品版本。

许多框架(例如 Django 或 Ruby on Rails)都内置了迁移系统或作为插件提供。您使用 SQLAlchemy 的案例有几个选择:

  1. 不要使用任何系统。只需手写/tmp/migrate.sql,写下 ALTER/DROP/CREATE 语句,交叉手指并将其应用于您的 SQLite 基础。这通常是一个坏主意,因为它容易出错,但选择取决于您。ALTER TABLE可以通过使用临时名称创建具有所需属性的新列、将原始列中的所有数据复制到其中、删除原始列并将新列重命名为原始名称来解决缺少全功能语句的问题。可以在表级别使用相同的技术。
  2. 使用一些 3rd-party 迁移系统,例如liquibase。Liquibase 很酷,设计精良且功能强大,除了一个缺点。这真的很麻烦。我为 SQLite 尝试了它(对 SQLAlchemy 来说是的,但实际上并不重要),但它没有做一些非常基本的事情。我搜索了一个问题,发现它们是已知的错误。
  3. 使用您提到的 SQLAlchemy-migrate。它不像受其启发的 ROR 迁移那样强大,也不像 liquibase 那样强大,但它确实有效。SQLite 限制可以以同样的方式解决。

您已经询问过如果您尝试删除列,SQLAlchemy-migrate 会做什么。好吧,它将删除一列,因此删除其中的所有数据。表中的其他列将保持不变。

于 2010-04-16T14:47:13.557 回答
5

sqlalchemy-migrate的最新替代方法是alembic,由 SQLAlchemy 的作者本人编写。尽管后者(“同一作者”)看起来像是一个强有力的论据,但缺点可能是它不支持 SQLite 的表 ALTERation,即它没有针对 SQLite 缺少 ALTER 支持的内置解决方法。(有人可能会说这超出了范围,可以通过专门的 python 包或 SQLite 扩展来解决。)

于 2012-05-16T09:26:46.340 回答
0

什么让你在 sqlalchemy-migrate 中感到困惑?它有 --preview_sql 和 --preview_py 选项来预览它要做什么。一般来说,不可能对任何可能的情况进行正确的迁移,但您可以修改生成的迁移脚本以满足您的需求。通过尝试很容易得到其余的答案。

于 2010-04-16T14:41:57.260 回答