使用SQLAlchemy和Elixir更新sqlite数据库架构

11

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

我的问题是:我该如何实现这一点?我知道sqlalchemy-migrate,但是我必须说我觉得它很难理解。它没有提到现有数据会发生什么变化。此外,sqlite对ALTER TABLE支持进行了缩减,那么如果我尝试删除列,迁移会发生什么?是否有其他方法来使用migrate?

3个回答

8

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

许多框架,例如Django或Ruby on Rails,具有内置的或可用作插件的迁移系统。使用SQLAlchemy的情况有几个选项:

  1. 不要使用任何系统,手写一个 /tmp/migrate.sql 文件,写下ALTER/DROP/CREATE语句,祈祷一下,然后应用到你的SQLite数据库中。这通常是一个坏主意,因为容易出错,但选择权在于你。缺少完整功能的 ALTER TABLE 语句可以通过创建具有所需属性的新列,使用临时名称,将所有数据从原始列复制到它,删除原始列,并将新列重命名为原始名称来解决。同样的技术也可以用于表级别。
  2. 使用一些第三方迁移系统,比如liquibase。Liquibase很酷,设计良好,功能强大,除了一个缺点。它真的很有bug。我尝试过在SQLite上使用它(当然还有SQLAlchemy),它未能完成一些相当基本的事情。我搜索了一些问题,并发现它们是已知的错误。
  3. 使用你提到过的SQLAlchemy-migrate。它不像受ROR-migrations启发的那么强大,也不像liquibase那么强大,但它是有效的。SQLite的限制可以以同样的方式解决。

您问到如果尝试删除列,SQLAlchemy-migrate会执行什么操作。它将删除该列并删除其中的任何数据。表中的其他列将保持不变。


5
sqlalchemy-migrate 的一个较新的替代方案是alembic,它由SQLAlchemy的作者本人编写。虽然后者(“同一作者”)看起来是一个强有力的论据,但其缺点可能是它不支持使用SQLite进行表ALTERation,即它没有针对SQLite缺失的ALTER支持的内置解决方法。(有人可能认为这超出了范围,并且可以通过专门的Python软件包或SQLite扩展来解决。)

0
在sqlalchemy-migrate中,你对什么感到困惑?它有--preview_sql和--preview_py选项,可以预览它将要执行的操作。总的来说,对于任何可能的情况,都不可能做出完全正确的迁移,但你可以修改生成的迁移脚本以适应你的需求。通过尝试,很容易找到其他问题的答案。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接