使用 alembic 创建数据库表和在 SQLAlchemy 中定义模型有什么区别?

What is the difference between creating db tables using alembic and defining models in SQLAlchemy?

我可以使用命令 alembic revision -m 'table_name' 创建表,然后使用 alembic upgrade head.

定义版本和迁移

此外,我可以通过在 models.py (SQLAlchemy) 中定义 class 来在数据库中创建表。

两者有什么区别?我很困惑。我搞砸了这个概念吗?

此外,当我使用 Alembic 迁移数据库时,为什么它没有在我的 models.py 中形成一个新的 class?我知道这些表已经创建,因为我使用 SQLite 浏览器检查了它们。

我已经完成了所有配置。 Alembic 数据库的目标和 config.py 中的 SQLALCHEMY_DATABASE-URI 是同一个 .db 文件。

是的,你想错了。

假设您不使用 Alembic 或任何其他迁移框架。在这种情况下,您可以通过以下步骤为您的应用程序创建一个新数据库:

  1. 写下你的模型类
  2. 创建并配置一个全新的数据库
  3. 运行 db.create_all(),它查看您的模型并在您的数据库中创建相应的表。

所以现在考虑升级的情况。例如,假设您发布了应用程序的 1.0 版,现在开始使用 2.0 版,这需要对您的数据库进行一些更改。你怎么能做到这一点?这里的限制是 db.create_all() 不修改表,它只能从头开始创建它们。所以它是这样的:

  1. 对您的模型进行必要的更改类
  2. 现在您有两个选项可以将这些更改传输到数据库:

    5.1 销毁数据库,这样你就可以再次运行 db.create_all() 得到更新的表,也许备份和恢复数据,这样你就不会丢失它。不幸的是,SQLAlchemy 对数据没有帮助,您必须为此使用数据库工具。

    5.2 手动将更改直接应用到数据库。这样容易出错,如果变更集很大的话会很乏味。

现在考虑您有开发和生产数据库,这意味着工作需要完成两次。还想一想如果您有多个应用程序版本,每个版本都有不同的数据库模式,并且您需要调查其中一个较旧版本中的错误,您需要重新创建数据库,因为它是在那个版本中发布。

看看你没有迁移网络是什么问题?

使用 Alembic,您在开始时需要做一些额外的工作,但它会带来回报,因为它简化了升级的工作流程。创建阶段是这样的:

  1. 写下你的模型类
  2. 创建并配置一个全新的数据库
  3. 手动或自动生成初始 Alembic 迁移。如果您使用自动迁移,Alembic 会查看您的模型并生成将这些模型应用于数据库的代码。
  4. 运行 upgrade 命令,它是 运行 迁移脚本,有效地在数据库中创建表。

然后当您到达升级点时,执行以下操作:

  1. 对您的模型进行必要的更改类
  2. 生成另一个 Alembic 迁移。如果您让 Alembic 为您生成它,那么它会将您的模型 类 与数据库中的当前模式进行比较,并生成使数据库与模型匹配所需的代码。
  3. 运行 upgrade 命令。这会将更改应用于数据库,而无需销毁任何表或备份数据。您可以 运行 在所有数据库(生产、开发等)上进行此升级。

使用 Alembic 时需要考虑的重要事项:

  • 迁移脚本成为您源代码的一部分,因此需要将它们与您自己的文件一起提交给源代码管理。
  • 如果您使用自动迁移生成,您总是需要查看生成的迁移。 Alembic 并不总是能够确定确切的更改,因此生成的脚本可能需要一些手动微调。
  • 迁移脚本具有 upgradedowngrade 功能。这意味着它们不仅可以简化升级,还可以简化降级。如果您需要将数据库同步到旧版本,downgrade 命令会为您完成,无需您做任何额外的工作!

我可以补充一点,Django 有两个命令

makemigrations (which creates migrations files) 
migrate (which translates migrations into sql and executes them on database)

我发现在包含电池的框架 (Django) 和其他框架(如 Flask/Falcon)之间切换对某些人的理解非常有用。

因此使用 alembic 迁移非常方便,并且可以轻松跟踪数据库更改。