如何使用sqlalchemy高效地pipe理频繁的模式更改?
我正在使用sqlalchemy编写Web应用程序。 在网站未投入生产的第一阶段,一切都很顺利。 我可以很容易地通过删除旧的sqlite数据库和从头开始创build一个新的数据库模式。
现在,网站正在生产中,我需要保留这些数据,但是我仍然希望通过轻松地将数据库转换为新的模式来保持原始开发速度。
所以我们假设在版本50中有model.py,在版本75中有model.py,描述了数据库的模式。 在这两个模式之间,大部分的改变是微不足道的,例如一个新的列被声明为一个默认值,我只是想把这个默认值添加到旧的logging。
最终,一些改变可能不是微不足道的,需要一些预先计算。
如何(或者将要)处理快速变化的Web应用程序,比如每天有一两个新版本的生产代码?
顺便说一句,如果这有什么不同,网站是写在主塔上。
Alembic是由SQLAlchemy的作者编写的一个新的数据库迁移工具。 我发现它比sqlalchemy-migrate更容易使用。 它也可以与Flask-SQLAlchemy无缝协作。
从SQLAlchemy模型自动生成模式迁移脚本:
alembic revision --autogenerate -m "description of changes"
然后将新的模式更改应用于您的数据库:
alembic upgrade head
更多信息: http : //readthedocs.org/docs/alembic/
使用sqlalchemy-migrate 。
它旨在支持敏捷的数据库devise方法,并且使开发和生产数据库保持同步更容易,因为需要更改模式。 它使架构版本化变得简单。
把它看作是你的数据库模式的版本控制。 您可以对每个模式进行更改,并且可以在模式版本上前后移动。 这样你就可以升级一个客户端,并且它会准确地知道在客户端的数据库上应用哪一组更改。
这就是S.Lott在他的回答中所提出的,自动为你准备的。 使困难的事情变得容易。
我们所做的。
-
使用您的应用程序的“主要版本”,“小版本”标识。 主版本是模式版本号。 主要的是没有一些随机的“足够的新function”的东西。 这是与数据库模式兼容的正式声明。
版本2.3和2.4都使用模式版本2。
版本3.1使用版本3架构。
-
使架构版本非常非常明显。 对于SQLite,这意味着将架构版本号保存在数据库文件名中。 对于MySQL,使用数据库名称。
-
编写迁移脚本。 2to3.py,3to4.py. 这些脚本分两个阶段工作。 (1)将旧数据查询成新的结构,创build简单的CSV或JSON文件。 (2)从简单的CSV或JSON文件加载新的结构,不作进一步处理。 这些提取文件 – 因为它们的结构正确,加载速度快,可以很容易地用作unit testing装置。 而且,你从来没有同时打开两个数据库。 这使脚本稍微简单一些。 最后,可以使用加载文件将数据移动到另一个数据库服务器。
模式迁移“自动化”非常非常困难。 使数据库手术如此深刻以至于自动化脚本无法轻易地将数据从旧模式映射到新模式是很容易的(也是常见的)。
处理你的问题的最好方法是反映你的模式,而不是声明式的方式。 我在这里写了一篇关于reflection方法的文章: http : //petrushev.wordpress.com/2010/06/16/reflective-approach-on-sqlalchemy-usage/,但也有其他资源。 以这种方式,每次对模式进行更改时,只需重新启动应用程序,reflection就会为表中的更改获取新的元数据。 这是非常快的,sqlalchemy每个进程只有一次。 当然,你必须pipe理你自己做的关系变化。