Ruby Rails should have data migration.

hooopo · 2012年07月20日 · 最后由 bhuztez 回复于 2012年08月02日 · 4928 次阅读

Rails 的 seed 和 migration 机制非常方便。 但是目前 Rails 里没有一个统一的 data migration 方案。对于修复临时数据这种需求,流行的做法是自己写脚本维护。但是这种做法有几个缺点:

1.没有统一的约定去组织这些文件 2.没有 generater 去生成 3.需要人为记录文件是否执行过 4.没有顺序

今天看到 ActiveDataMigration 这个 gem 的介绍,感觉不错。

大家也可以来讨论一下实际项目中对临时性数据修复这样的工作的做法和遇到的问题。

相关链接:

http://www.mcdonaldland.info/2012/07/17/rails-data-migrations-made-easy/ https://github.com/finn0013/active_data_migrations http://rubylution.herokuapp.com/topics/8

共收到 32 条回复

临时修复的需求我都是写在 seeds 里面,允许完以后就去掉代码。 这种做法还有个问题是,如果是开源项目,那其他拿取用,并且有数据的用户就悲剧了。

修复临时数据是指什么?

#2 楼 @fredwu 1.应用运行中出现的 bug,导致数据完整性的问题,但是这部分数据已经进入了生产环境数据库。 2.一些功能/需求改变,导致需要对原来的数据进行迁移

我们现在是写 sql 或者 rake task.

#4 楼 @fresh_fish 这是流行的做法,但是没有解决我上面提到的 4 个问题啊 理想状况是:

rails g data_migration fix_blog_body
rake db:data:migrate:status RAILS_ENV=xx
rake db:data:migrate RAILS_ENV=xx

我自己的经验,用 Migration 来修改数据库的 Schema,用 rake task 来修复或者迁移数据。 每次 production 环境的数据 schema 变更和数据迁移都是一件非常谨慎的事,特别是你面对的数据库非常大的时候,往往做一次 migration 需要非常长的时间,所以这个事情除了靠自动化工具之外,更主要还是依靠人,特别是制定周全的计划,并谨慎按照计划来执行。

#6 楼 @lgn21st 我也是这样,另外,如果可能,最好直接导出线上数据,预先测试一下迁移代码

#7 楼 @fsword 是的,但凡稍微大一点的数据迁移事务,我也是导出线上数据在本地测试千百遍~

#6 楼 @lgn21st 预测和谨慎与自动化工具不冲突。 自动化工具主要起一个约定目录结构和给迁移文件排列顺序的作用。 人制定计划之后如果能形成自动化任务一定比手动执行快,减少宕机时间。 由于 Rails 没重视 data migration 这一部分内容,大部分普通开发者没有处理这种情况的经验,经常遇到在 migration 里写迁移数据的代码(滑板书里面也没反对这么做),最终导致 rails migrate 跑不起来了。

其实就是应该提出一个 data migration 最佳实践,并形成规范。一则减少风险,二则提高数据迁移效率

Django+South 妥妥的

#11 楼 @bhuztez south 是把 migration 信息存在数据库里么?

#12 楼 @fleuria

south 是把 migration 信息存在数据库里么?

只有 migration 的历史信息 (什么时间执行了哪个 migration) 是记录在数据库里的

https://bitbucket.org/andrewgodwin/south/src/tip/south/models.py

#11 楼 @bhuztez 呃 还真不错 不过这东西用递增序列做版本号不怕多人开发的时候冲突么? South 是第三方工具。。这么说 django 貌似没有 schema migration?

#14 楼 @hooopo

South 是第三方工具。。这么说 django 貌似没有 schema migration?

South 现在基本上就是等着被官方合并的状态。

Django 官方已经意淫了两年了

https://code.djangoproject.com/wiki/SummerOfCode2011#SchemaAlteration https://code.djangoproject.com/wiki/SummerOfCode2012#SchemaAlteration

#14 楼 @hooopo

不过这东西用递增序列做版本号不怕多人开发的时候冲突么?

开发的时候你在 models.py 里定义 Model。只是在最后部署的时候,让 South 生成一下 migration 文件。

#14 楼 @hooopo 前几天问过身边搞 py 的朋友,好几人都说"一般没有调整 schema 的需求吧"。刚开始还是很难适应的。

#15 楼 @bhuztez south 是怎样解决本贴提到的问题的呢?

#18 楼 @fleuria

1.没有统一的约定去组织这些文件

South 规定了 migration 文件怎么写,放哪里

2.没有 generater 去生成

只要有可能,South 会尽量为你生成更多东西

3.需要人为记录文件是否执行过

记录在数据库里

4.没有顺序

South 规定要有顺序

#20 楼 @fleuria South 并不严格区分 schema migration 和 data migration,对于 data migration,South 生成一个模板,你自己往里填内容。其实,schema migration 你也可以用datamigration生成模板,并在那个基础上改改的。无非schemamigration那个命令,会自动检查 model 的变化,尽可能帮你自动生成而已。

South 就只认,migration 文件里的Migrationforwardbackward两个函数,在这两个函数里,你既可以做 data migration 也可以做 schema migration。

当然了,实际上,两个命令会生成不同的模板,一个class Migration(DataMigration),一个class Migration(SchemaMigration)

#21 楼 @bhuztez 这两个东西放在一起吗

#22 楼 @hooopo 你这个放在一起指什么?

South 就只认,migration 文件里的Migrationforwardbackward两个函数,在这两个函数里,你既可以做 data migration 也可以做 schema migration。

当然了,实际上,两个命令会生成不同的模板,一个class Migration(DataMigration),一个class Migration(SchemaMigration)

这个是补上面的,囧...

#23 楼 @bhuztez 别再说了,south 技止此尔。它解决的本来就是 rails 中不存在的问题,但跟本贴中提到的问题无关。

看来 @bhuztez 完全没了解过 Rails 就来推广 Django。

http://guides.rubyonrails.org/migrations.html

#23 楼 @bhuztez 举个例子: 我产生了一个 schema/0001_create_users 这样一个 schema 迁移 然后又生成了一个 data migration,名字叫 data/xxx_migrate_title

我的问题是: 1.这个 data migration 的名字是 data/0001_migrate_titile 还是 schema/0002_migrate_title. 2.执行迁移命令时候是一起执行还是单独执行

如果是一起的,那就和 rails 目前的 migration 一样了。修改 schema 的 migration 也可以修改 data。但不是我想要的。

#26 楼 @hooopo 我觉得这是 ActiveRecord 视角的问题。从 ActiveRecord 的角度看,schema 是根据 migration 文件的操作结果计算出来的。而从 DataMapper 的视角看,migration 文件是根据 schema 的变化生成出来的。因为你开发的时候并不需要准备好的 migration 文件,schema migration 和 data migration 放在一起并不是什么问题,但也不希望这么干的。

Update:
上面是说开发的branch里可以完全不放migration代码。这样哪怕migration烂掉也无所谓。但从洁癖出发,还是别烂掉好。所以才有下面。

在 Django 里,按照 Django 的代码组织风格,是分 project 和 app 的。一般不在 project 里定义 model。app 发布的时候要带上 migration 文件,处理 schema migration。而临时性的 data migration 就放在 project 下了。因为每个 app 的自增数列是独立的,所以就没问题了。

myproject/
    migrations/    <- 临时的
        0001_data_...
        0002_data_...
        ...
myapp1/
    migrations/
        0001_schema_...
        0002_schema_...
        ...
myapp2/
    migrations/
        0001_schema_...
        0002_schema_...
        ...
...

按 Rails 的说法,就是项目?里不准定义 model,全在 Engine 里定义,每个 Engine 的 migration 的自增数列是独立的,临时性的 data migration 统一在项目里做。

#24 楼 @fleuria 有关啊。South 能做 migration,South 的风格刚好和 LZ 想要的一致。而按 Django 本身的约定,天然就把临时的和与代码相关的 migration 分在 project 和 app 里了。这问题自然就结了。

#28 楼 @bhuztez 你说的大家都懂,可是楼主说的什么你真的确定看明白了么。 不学下 rails,不让实际的项目多虐几下,凭自己在 django 里面了解的经验就能理解了别人在说什么? 太轻巧了。世界真这么美好就好了。不用学我就比你们还懂 rails,不用学我就比你们更清楚 rails 的弱点在哪儿,不用学我就能指点你们该怎样解决现实问题。 哪怕花上半个星期草草过上一遍 rails guide,也不至于说这些天真的话出来。

#29 楼 @fleuria

你说的大家都懂,可是楼主说的什么你真的确定看明白了么。 不学下 rails,不让实际的项目多虐几下,凭自己在 django 里面了解的经验就能理解了别人在说什么?

migration 的需求来自哪里?来自 RDBMS。因为你有了 schema,你才要 migrate。只要会用 SQL 的,都能理解这个问题。无论你用 CGI 还是 ASP 还是 PHP 问题都是一样的,和框架有关的只是框架对这类需求提供何种程度的支持。而临时转换数据只是恰好能通过这种机制来处理罢了。

太轻巧了。世界真这么美好就好了。不用学我就比你们还懂 rails,不用学我就比你们更清楚 rails 的弱点在哪儿,不用学我就能指点你们该怎样解决现实问题。

我从头到尾说的都是 Django+South 刚好没这个问题,从头到尾都没说过如何在 Rails 里解决这问题吧。不知道你是怎么看出来的。

哪怕花上半个星期草草过上一遍 rails guide,也不至于说这些天真的话出来。

你是怎么得出我没看过 Rails Guide 的结论的。如果你指的是 Rails 3.x,那我的确没有。但我有必要告诉你我看过 Rails 2.x 的 Guide,看过 3.0/3.1/3.2 的 ChangeLog 么?我有必要告诉你我折腾过几个 Rails 项目么?这些都是 BS,说出来一点信息量都没有,不是么?

#30 楼 @bhuztez 提醒过你了,你没看贴。或者有人告诉你,rails 的 migration 里面不能改数据么?这是坏味道,没人这么做罢了。

#31 楼 @fleuria 我知道问题在哪里了。我之前一直在强调的是有了 South,Django 也可以像 Rails 那样做 migration 了,schema migration 也是可以和 data migration 放在一起的。我认为剩下的部分是很显然的就没说了。

那从头来过:

首先是 migration 本身

  • migration 是因为 RDBMS 有 schema 才出现的需求
  • 有时候 schema migration,也会附带需要转换数据,所以 migration 需要支持 data migration
  • 恰好,临时的数据转换,也可以通过这个机制来做

接着 Django+South

  • Django 本身没有 migration 的功能。South 为 Django 提供了必要的 migration 功能
  • 按照 Django 的风格,和 schema 变化有关的 migration 应该放在 app 里,临时的 data migration 放在 project 里,这样就避免了坏味道。

之前的分歧就在于,

我说的是,和 schema 变化有关的 data migration 是可以 schema migration 放在一起。 你想要的是,和schema变化有关的migration临时的data migration,这两个应该放在不同的地方。

这样应该没问题了吧。上面的确是有一些回得太快了,没注意上下文的。漏的引用啥的,我都补了下。

hooopo Not All Migrations are Equal: Schema vs. Data 中提及了此贴 08月17日 00:33
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册