跳转到主要内容

为SQLAlchemy的适度简单模式升级。

项目描述

演示

典型用途

import sqlalchemy
import stucco_evolution

engine = sqlalchemy.create_engine(...)

with engine.begin() as connection:
    stucco_evolution.initialize(connection)
    stucco_evolution.create_or_upgrade_packages(connection, 'mypackage')

stucco_evolution在其自身、'mypackage'及其依赖项的事务中创建或升级数据库模式,按照正确的、拓扑排序的顺序。

摘要

stucco_evolution的独特之处在于,它可以将相关的数据库模式作为单独的包发布,而不是必须统一管理。通过跟踪模式之间的依赖关系,例如,在创建或升级更具体的应用程序表之前,会自动创建或升级User / Group模型等表。目的是提高数据库代码的重用性。

stucco_evolution扩展了repoze.evolution以支持SQLAlchemy。它提供了一种简单的方法,在单个包内作为一系列编号的Python脚本实现模式迁移,并提供了一种方式,让包可以相互依赖,形成一个有向无环图,按照拓扑依赖顺序创建和升级每个模式的表。

stucco_evolution按顺序将SQLAlchemy连接传递给编号脚本包,记录已安装模式的版本,并按依赖顺序对一组evolve包进行排序。它将实际编写ALTER TABLE语句的工作委托给另一个库或您的头脑。它将模式降级委托给适当的数据库备份。

stucco_evolution 是作为支持代码编写用于 Web 应用程序的,然后从中提取出来,扩展,并发布。现在打算用它来管理自身和其他将来要发布的 stucco_* 软件包的数据库模式。希望您也会觉得它对您的软件包有用。然而,此软件按“原样”提供,不提供任何明确的或隐含的保证,包括但不限于适销性和适用于特定目的的隐含保证。

用法

如果您的软件包名为 mypackage,您可以添加一个名为 evolve 的演变模块。此模块将包含用于从当前版本迁移到下一个版本的脚本。

cd mypackage
mkdir evolve
touch evolve/__init__.py

evolve/__init__.py 必须包含三个常量

NAME = 'mypackage' # stucco_evolution imports 'mypackage' + '.evolve'
VERSION = 0
DEPENDS = []

evolve/create.py 应始终创建当前版本 VERSION 的数据库模式。它应该是幂等的

def create(connection):
    import mypackage.models
    mypackage.models.Base.metadata.create_all(connection)

(如果您已安装 Paste Script,您可以输入 paster create -t stucco_evolution [mypackage] 在 [mypackage]/evolve 中创建一个演变模块。由于 Paste Script 的包名替换并不完美,请检查 mypackage/evolve/__init__.py 确保可以导入 NAME + ‘.evolve’。)

现在您可以创建您版本的数据库模式

import sqlalchemy
import stucco_evolution

engine = sqlalchemy.create_engine(...)

with engine.begin() as connection: # engine.begin() since SQLAlchemy 0.7.6
    stucco_evolution.initialize(connection)
    stucco_evolution.create_or_upgrade_packages(connection, 'mypackage')

在此模式中,stucco_evolution 尝试创建 mypackage 及其所有依赖项的数据库模式,如果它们目前没有在 stucco_evolution 表中跟踪,则按拓扑顺序创建。对于特定的数据库模式 VERSION,演变脚本必须负责创建新表。

最终 mypackage 将需要一个新的 VERSION。为此,您必须将 VERSION 增加到 N,并在演变模块中添加 evolve/evolveN.py

evolve/__init__.py:

NAME = 'mypackage'
VERSION = 1
DEPENDS = []

evolve/evolve1.py:

def evolve(connection):
    connection.execute("CREATE TABLE foo (bar INTEGER)")
    connection.execute("ALTER TABLE baz ADD COLUMN quux INTEGER")

下次您调用 create_or_upgrade(…) 时,stucco_evolution 将注意到 mymodule 已在 stucco_evolution 表中跟踪,但其数据库版本小于 mymodule.evolve.VERSION。为了纠正这一点,stucco_evolution 将调用大于数据库版本的每个 evolveN.py,以使数据库保持最新。

在依赖项的情况下,stucco_evolution 将尝试在升级其依赖项之前,先创建或使每个依赖项包完全更新。依赖项支持是一个实验性功能。

省略的功能

没有为降级脚本提供支持。我曾经自己编写它们,但从未使用过它们。相反,备份您的数据库,并在临时测试数据库中进行测试。

没有 DDL 抽象库。请随意使用您喜欢的任何库,或者自己编写 ALTER TABLE 语句。

健壮的升级脚本

如果您足够自大,将您的软件包作为另一个软件包的依赖项发布,或者它将被广泛安装,您需要确保您的升级脚本健壮。最重要的规则

  • 新代码永远不能改变旧演变脚本的输出。

实现这一点的最简单方法是作为文本发出所有 DDL,并在 evolve 脚本或仅在创建脚本中导入您的包以及调用 SQLAlchemy 的 create_all()。您还可以尝试按照 sqlalchemy-migrate 的建议将您的模型复制粘贴到每个 evolve 脚本中,以便 SQLAlchemy 生成 DDL。您还可以保留每个版本的模式备份,并编写测试以恢复每个备份并将其升级到最新版本,以确保这对于所有先前版本都保持可能。

0.4

  • create_many() 检查模式是否已安装

0.35

  • 修复清单以正确包含 paster 模板

  • 删除不必要的 argparse 依赖

0.34

  • paster create -t stucco_evolution mypackage 添加到在 mypackage/evolve/… 中创建演变模块

0.33

  • 向后不兼容的更改。现在在之前期望会话的地方需要一个 SQLAlchemy 连接。这对于事务 DDL(能够回滚抛出异常的迁移)是必要的。

0.12

  • 添加创建或升级软件包的便捷函数create_or_upgrade_packages(session, 'packagename')

0.11

  • 向后不兼容的API更改

  • 改进文档

  • 检测进化模块之间的循环依赖

  • 恢复100%的语句覆盖率(然而,单元测试依赖于几个尚未发布的软件包)

0.10

  • 添加支持DAG排序依赖的多软件包架构进化

0.9

  • 重命名为stucco_evolution

  • 现在stucco_evolution的自己的upgrade()会将所有stucco_evolution.Base.metadata.create_all(session)委托到evolveN.py脚本中。这避免了在升级包括表重命名时出现'DROP TABLE'语句。

0.8998

  • 提高了可打包性(已指定MANIFEST.in)

  • SQLAlchemyEvolutionManager不再调用session.commit();在迁移完成后,这是您的责任。

0.8

  • 100%的语句覆盖率

0.0

  • 初始版本

项目详情


下载文件

下载适合您平台的文件。如果您不确定选择哪个,请了解有关安装软件包的更多信息。

源代码分发

stucco_evolution-0.50.0.tar.gz (12.0 kB 查看哈希)

上传时间 源代码

构建分发

stucco_evolution-0.50.0-py3-none-any.whl (11.3 kB 查看哈希)

上传时间 Python 3

支持者:

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误日志 StatusPage StatusPage 状态页面