MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

Modelo de mudança de tempo de execução com mongodb/mongoid


Em geral, deve ser possível atualizar documentos antigos com os novos campos em tempo de execução. Não há necessidade de migrações no MongoDB.

Talvez você queira escrever tarefas de rake para atualizar seus documentos antigos com os novos campos e valores padrão.

Você pode descobrir esses documentos verificando os novos campos que têm por padrão um valor nulo.

Atualizar

Estilo fácil:

Se você definir um novo campo com um valor padrão, esse valor sempre deve ser usado desde que você defina um novo:

app/models/my_model.rb
class MyModel
  include Mongoid::Document
  field :name, type: String
  field :data, type: String
  # NEW FIELD
  field :note, type: String, default: "no note given so far!"
end

Se você consultar seu banco de dados, deverá obter seu valor padrão para documentos que não tenham este campo antes de sua extensão:

(console de trilhos)
MyModel.first
#=> #<MyModel …other fields…, note: "no note given so far!">

Eu testei isso com uma nova pilha de trilhos com um mongoid atual no Ruby 1.9.2 - deve funcionar com outras pilhas também.

Estilo mais complicado/complexo:

Se você não definiu um valor padrão, receberá nil para este novo campo.

app/models/my_model.rb
class MyModel
  include Mongoid::Document
  field :name, type: String
  field :data, type: String
  # NEW FIELD
  field :note, type: String
end

(console de trilhos)
MyModel.first
#=> #<MyModel …other fields…, note: nil>

Então você pode configurar uma tarefa de rake e um arquivo de migração como neste exemplo:

lib/tasks/my_model_migration.rake:
namespace :mymodel do
  desc "MyModel migration task"
  task :migrate => :environment do
    require "./db/migrate.rb"
  end
end

db/migrar.rb:
olds = MyModel.where(note: nil)
# Enumerator of documents without a valid :note field (= nil)
olds.each do |doc|
  doc.note = "(migration) no note given yet"
  # or whatever your desired default value should be
  doc.save! rescue puts "Could not modify doc #{doc.id}/#{doc.name}"
  # the rescue is only a failsafe statement if something goes wrong
end

Execute esta migração com rake mymodel:migrate .

Este é apenas um ponto de partida e você pode estender isso para um mecanismo de migração mongoid completo.

A task :migrate => :environment do … é necessário, caso contrário, o rake não carregará os modelos.