MongoMapper 和迁移

发布于 2024-08-12 01:59:50 字数 1141 浏览 5 评论 0原文

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

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 的初始值(在 version1 -> version2 迁移中)并删除 some_key 的值(在 version2 -> version3 迁移中)。

使用 MongoDB/MongoMapper 执行此操作的适当方法是什么?在我看来,仍然需要某种方法来跟踪已运行的迁移。这样的事存在吗?

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

I'm building a Rails application using MongoDB as the back-end and MongoMapper as the ORM tool. Suppose in version 1, I define the following model:

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

Later in version 2, I realize that I need a new required key on the model. So, in version 2, SomeModel now looks like this:

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

How do I migrate all my existing data to include some_new_key? Assume that I know how to set a reasonable default value for all the existing documents. Taking this a step further, suppose that in version 3, I realize that I really don't need some_key at all. So, now the model looks like this

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

But all the existing records in my database have values set for some_key, and it's just wasting space at this point. How do I reclaim that space?

With ActiveRecord, I would have just created migrations to add the initial values of some_new_key (in the version1 -> version2 migration) and to delete the values for some_key (in the version2 -> version3 migration).

What's the appropriate way to do this with MongoDB/MongoMapper? It seems to me that some method of tracking which migrations have been run is still necessary. Does such a thing exist?

EDITED: I think people are missing the point of my question. There are times where you want to be able to run a script on a database to change or restructure the data in it. I gave two examples above, one where a new required key was added and one where a key can be removed and space can be reclaimed. How do you manage running these scripts? ActiveRecord migrations give you an easy way to run these scripts and to determine what scripts have already been run and what scripts have not been run. I can obviously write a Mongo script that does any update on the database, but what I'm looking for is a framework like migrations that lets me track which upgrade scripts have already been run.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

思慕 2024-08-19 01:59:50

看看 Mongrations...我刚刚读完它,它看起来就像你想要的。

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

http://github.com/terrbear/mongrations

干杯!卡普斯洛克

Check out Mongrations... I just finished reading about it and it looks like what you're after.

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

http://github.com/terrbear/mongrations

Cheers! Kapslok

咋地 2024-08-19 01:59:50

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

One option is to use the update operation to update all of your data at once. Multi update is new in the development releases so you'll need to use one of those.

风为裳 2024-08-19 01:59:50

您可以尝试我刚刚制作的这个装置,但它目前仅适用于 mongoid 和 Rails 3(beta 3)。 http://github.com/adacosta/mongoid_rails_migrations 。当它最终完成时,它将升级到 Rails 3。

You can try this contraption I just made, but it only works with mongoid and rails 3 (beta 3) at the moment. http://github.com/adacosta/mongoid_rails_migrations . It'll be upgraded to rails 3 when it goes final.

香草可樂 2024-08-19 01:59:50

也是 MongoMapper 迁移的另一个宝石 https://github.com/alexeypetrushin/mongo_mapper_ext

Also another gem for MongoMapper migrations https://github.com/alexeypetrushin/mongo_mapper_ext

穿透光 2024-08-19 01:59:50

Mongrations 是一个超级古老的宝石,完全被弃用。我建议不要使用它。

Exodus 是一个非常酷的 Mongo 迁移框架,这可能就是您想要的:

https://github.com/ThomasAlxDmy/出埃及记

Mongrations is a super old gem, completely deprecated. I recommend NOT using it.

Exodus is a really cool migration framework for Mongo, that might be what you want:

https://github.com/ThomasAlxDmy/Exodus

黑白记忆 2024-08-19 01:59:50

我们只是构建这个:https://github.com/eberhara/mongration - 它是一个常规节点模块(你可以在 npm 上找到它)。

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

它比常规迁移框架有很多更好的功能:

  • 校验和(当之前运行的迁移与其旧版本不匹配时发出错误)
  • 将迁移状态保留到 mongo(没有常规状态文件)
  • 完全支持副本集
  • 自动处理回滚(开发人员必须指定回滚过程)
  • 能够同时运行多个迁移(同步或异步)
  • 能够同时针对不同数据库运行迁移

希望它有所帮助!

We just build this one: https://github.com/eberhara/mongration - it is a regular node module (you can find it on npm).

We needed a good mongodb migration framework, but could not find any - so we built one.

It has lot's of better features than the regular migration frameworks:

  • Checksum (issues an error when a previosuly ran migration does not match its old version)
  • Persists migration state to mongo (there is no regular state file)
  • Full support to replica sets
  • Automatic handle rollbacks (developers must specify the rollback procedures)
  • Ability to run multiple migrations (sync or async) at the same time
  • Ability to run migrations against different databases at the same time

Hope it helps!

如梦 2024-08-19 01:59:50

克林特,

您可以编写代码来进行更新 - 尽管似乎不支持根据其自己的字段更新记录。

在这种情况下,我执行了以下操作并对服务器运行它:

------------------------------
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
------------------------------

Clint,

You can write code to do updates -- though it seems that for updating a record based on its own fields is not supported.

In such a case, I did the following and ran it against the server:

------------------------------
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
------------------------------
攀登最高峰 2024-08-19 01:59:50

我打赌您可以连接到 Activerecord::Miration 来自动化和跟踪您的“迁移”脚本。

I bet you could hook into Activerecord::Miration to automate and track your "migration" scripts.

恰似旧人归 2024-08-19 01:59:50

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

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

我自己对 MongoDB 相当陌生,但据我所知,由于无模式数据库的灵活性,这就是您需要处理它的方式。

MongoDB is a schema-less database. That's why there are no migrations. In the database itself, it doesn't matter whether the objects have the key :some_key or the key :some_other_key at any time.

MongoMapper tries to enforce some restrictions on this, but since the database is so flexible, you will have to maintain those restrictions yourself. If you need a key on every object, make sure you run a script to update those keys on pre-existing objects, or handle the case of an object that doesn't have that key as you come across them.

I am fairly new to MongoDB myself, but as far as I can see, due to the flexibility of the schema-less db this is how you will need to handle it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文