2009-11-19 53 views
22

我构建了一个使用MongoDB作为后端和MongoMapper作为ORM工具的Rails应用程序。假设在版本1中,我定义了以下型号:MongoMapper和迁移

class SomeModel 
    include MongoMapper::Document 
    key :some_key, String 
end 

在版本2的后面,我意识到我需要一个新的模型所需的密钥。因此,在第2版,SomeModel现在看起来是这样的:

class SomeModel 
    include MongoMapper::Document 
    key :some_key, String 
    key :some_new_key, String, :required => true 
end 

我如何迁移我的所有现有数据,包括some_new_key?假设我知道如何为所有现有文档设置合理的默认值。进一步说,假设在版本3中,我意识到我真的不需要some_key。所以,现在的模型看起来像这样

class SomeModel 
    include MongoMapper::Document 
    key :some_new_key, String, :required => true 
end 

但这一切在我的数据库中的现有记录有some_key设置的值,它只是在这一点上浪费空间。我如何回收这个空间?

使用ActiveRecord,我可以创建迁移以添加some_new_key(在版本1 - >版本2迁移中)的初始值,并删除some_key(在版本2 - >版本3迁移中)的值。

用MongoDB/MongoMapper做这件事的适当方法是什么?在我看来,跟踪哪些迁移已经运行的一些方法仍然是必要的。这样的事情存在吗?

编辑:我认为人们错过了我的问题。有时您希望能够在数据库上运行脚本来更改或重构其中的数据。上面给出了两个示例,一个是添加了新的必需密钥,另一个是可以移除密钥并可以回收空间的示例。你如何管理这些脚本的运行? ActiveRecord迁移为您提供了一种简单的方法来运行这些脚本,并确定哪些脚本已经运行,哪些脚本尚未运行。我显然可以编写一个Mongo脚本来对数据库进行任何更新,但是我期待的是一个像迁移这样的框架,可以让我跟踪哪些升级脚本已经运行。

+0

我认为Mongo(/ Mapper)可能对于这种事情太年轻了。 :/ – Konklone 2010-01-05 20:04:23

+0

由于Mongo DB实际上没有任何模式,所以在模式方面的迁移实际上并不是一个适当的概念。您需要自己编写数据迁移脚本。 – zsong 2012-01-26 21:39:44

回答

13

检查Mongrations ...我刚读完它,它看起来像你在做什么。

http://terrbear.org/?p=249

http://github.com/terrbear/mongrations

干杯! Kapslok

+1

对于Rails 3,请查看terrbear的mongrations这个分支:https://github.com/TheHiveProjects/mongrations。 (在撰写本文时,这是具有最近提交的分支)。我必须指定'gem'mongrations',:git =>'git:// github.com/TheHiveProjects/mongrations.git'来获取它上班。 – colllin 2012-02-20 04:36:57

-5

MongoDB是一个无模式数据库。这就是为什么没有迁移。在数据库本身中,对象是否随时都有键:some_key或键:some_other_key并不重要。

MongoMapper试图强制执行一些限制,但由于数据库非常灵活,您将不得不自己维护这些限制。如果您需要每个对象上的一个键,请确保您运行一个脚本来更新预先存在的对象上的这些键,或者处理在碰到它们时没有该键的对象。

我对MongoDB本人相当陌生,但据我所见,由于无模式数据库的灵活性,因此您需要如何处理它。

+9

我对这个问题抱有疑问:“MongoDB是一个无模式数据库,这就是为什么没有迁移的原因。” 虽然MongoDB并未在您的文档中实施架构,但实际上您可能希望您的应用程序在某种程度上强制执行架构。 如果您更广泛地定义“迁移”,可以很容易地看到MongoDB支持的Web应用程序可能需要迁移。确实,一种迁移是“正式的”模式迁移。但还有其他类型的迁移仍然非常重要:添加密钥,重命名密钥,更改数据等。 – 2010-02-23 21:51:00

+11

数据转换是迁移。 MongoDB有数据。 – 2010-04-20 19:07:49

1

一种选择是使用update操作一次更新所有数据。多版本更新在开发版本中是新的,因此您需要使用其中的一种。

-1

我敢打赌,你可以勾选Activerecord :: Miration来自动化和跟踪你的“迁移”脚本。

0

克林特,

您可以编写代码来执行更新 - 尽管这似乎是更新基于自身领域的纪录不被支持。

在这种情况下,我做了以下并运行它针对服务器:

------------------------------ 
records = Patient.all() 

records.each do |p| 
    encounters = p.encounters 
    if encounters.nil? || encounters.empty? 
    mra = p.updated_at 
    #puts "\tpatient...#{mra}" 
    else 
    mra = encounters.last.created_at 
    #puts "\tencounter...#{mra}" 
    end 
    old = p.most_recent_activity 
    p.most_recent_activity = mra 
    p.save! 
    puts "#{p.last_name} mra: #{old} now: #{mra}" 
end 
------------------------------ 
1

我们只是建立这一个:https://github.com/eberhara/mongration - 这是一个普通节点模块(你可以找到它NPM)。

我们需要一个很好的mongodb迁移框架,但找不到任何 - 所以我们建立了一个。

它拥有比普通移民框架更完善的功能很多的:

  • 校验(发布时previosuly跑迁移不匹配其旧版本错误)
  • 持续迁移状态蒙戈(有没有固定的状态文件)
  • 到副本全面支持设置
  • 自动把手回滚(开发商必须指定回滚过程)
  • 能力MULTIP运行乐迁移的同时(同步或异步)
  • 能够在同一时间

希望它可以帮助运行不同数据库的迁移!