使用sqlalchemy和elixir更新sqlite数据库模式

时间:2010-04-16 11:06:05

标签: python database sqlalchemy python-elixir sqlalchemy-migrate

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

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

3 个答案:

答案 0 :(得分:8)

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

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

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

答案 1 :(得分:5)

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

答案 2 :(得分:0)

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