【问题标题】:What is the difference between creating db tables using alembic and defining models in SQLAlchemy?使用 alembic 创建数据库表和在 SQLAlchemy 中定义模型有什么区别?
【发布时间】:2015-08-06 03:49:59
【问题描述】:

我可以使用命令alembic revision -m 'table_name' 创建表,然后定义版本并使用alembic upgrade head 进行迁移。

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

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

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

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

【问题讨论】:

    标签: python flask sqlalchemy alembic


    【解决方案1】:

    是的,你想错了。

    假设您不使用 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 命令会为您完成,而无需您做任何额外的工作!

    【讨论】:

    • 非常感谢。这几乎为我清除了一切。我仍然有一些问题。通过进行手动迁移,您的意思是,在向模型添加新类或修改模型中的现有类之后,我需要使用“alembic revision -m 'tablename'”在 alembic 中进行新的迁移。然后在版本文件夹中,我必须编辑(定义)新创建的 .py 文件以匹配我刚刚定义的模型类?手动操作是个好习惯吗?
    • 对。手动迁移需要您自己编写 upgradedowngrade 函数,无需 Alembic 的帮助。自动迁移生成相当好,所以我更喜欢自动生成一个脚本,然后我检查它并在必要时进行任何更正,显然在我运行upgrade之前。
    • @Miguel 感谢您的总结。这有助于我更好地理解一般的开发流程。正如您所指出的,升级的好处之一是它保留了数据,但是当我运行降级然后升级到反向时会发生什么,这会破坏数据吗?
    • 是的,降级会破坏需要删除的表中的数据。如果您再次升级,您将获得全新的空表。
    【解决方案2】:

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

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

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

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

    【讨论】:

      猜你喜欢
      • 2017-04-29
      • 1970-01-01
      • 2020-01-24
      • 1970-01-01
      • 1970-01-01
      • 2017-06-11
      • 2014-07-27
      • 2011-03-31
      相关资源
      最近更新 更多