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

Altere o tipo de campo no Mongoid sem perder dados


Ok consegui passar. Acho que existe uma maneira mais rápida de usar o console do mongo com algo assim:MongoDB:Como alterar o tipo de um campo?

Mas não consegui fazer a conversão funcionar, então optei por esse método mais lento no console do rails com mais tempo de inatividade. Se alguém tiver uma solução mais rápida por favor poste.
  • crie um novo campo Integer com um novo nome, digamos amount2
  • converter cada amount para o valor correto para amount2 em um console ou tarefa de rake


Mongoid.identity_map_enabled = false
Transaction.all.each_with_index do |t,i|
  puts i if i%1000==0
  t.amount2 = t.amount.to_money
  break if !t.save
end

Observe que .all.each funciona bem (você não precisa usar .find_each ou .find_in_batches como activerecord regular com mysql) por causa dos cursores mongodb. Ele não encherá a memória enquanto o identity_map estiver desativado.

  • desative o site para manutenção, execute a migração mais uma vez para capturar quaisquer campos de quantidade que possam ter sido alterados nos últimos minutos (algo como Transaction.where(:updated_at.gt => 1.hour.ago).each_with_index...

  • comente field :amount, type: BigDecimal no seu modelo, você não quer que o mongoid saiba mais sobre esse campo e envie este código
  • agora execute outro script para renomear sua coluna (ele substitui qualquer valor de string BigDecimal antigo no processo). Talvez seja necessário comentar quaisquer validações que você tenha no modelo que espera o campo antigo.


Mongoid.identity_map_enabled = false
Transaction.all.each_with_index do |t,i|
  puts i if i%1000==0
  t.rename :amount2, :amount
end

Isso é atômico e não requer salvar o modelo.
  • atualize seu modelo para refletir o novo tipo de coluna field :amount, type: Integer
  • implante e reative o site

Como mencionado, acho que há uma maneira melhor, então se alguém tiver algumas dicas, por favor, compartilhe. Obrigado!