sql >> Base de Datos >  >> NoSQL >> MongoDB

Cambiar tipo de campo en Mongoid sin perder datos

Ok, lo logré. Creo que hay una forma más rápida de usar la consola mongo con algo como esto:MongoDB:¿Cómo cambiar el tipo de un campo?

Pero no pude hacer que la conversión funcionara, así que opté por este método más lento en la consola de rieles con más tiempo de inactividad. Si alguien tiene una solución más rápida, publíquela.

  • cree un nuevo campo Integer con un nuevo nombre, digamos amount2
  • convertir cada amount al valor correcto para amount2 en una consola o tarea 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

Tenga en cuenta que .all.each funciona bien (no necesita usar .find_each o .find_in_batches como activerecord regular con mysql) debido a los cursores mongodb. No llenará la memoria mientras el Identity_map esté desactivado.

  • desactive el sitio para mantenimiento, ejecute la migración una vez más para capturar cualquier campo de cantidad que podría haber cambiado en los últimos minutos (algo así como Transaction.where(:updated_at.gt => 1.hour.ago).each_with_index...

  • comentar el campo field :amount, type: BigDecimal en su modelo, no quiere que mongoid sepa más sobre este campo, y presione este código

  • ahora ejecuta otra secuencia de comandos para cambiar el nombre de tu columna (sobrescribe cualquier valor antiguo de cadena BigDecimal en el proceso). Es posible que deba comentar cualquier validación que tenga en el modelo que espera el campo anterior.

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

Esto es atómico y no requiere guardar el modelo.

  • actualice su modelo para reflejar el nuevo tipo de columna field :amount, type: Integer
  • implementar y recuperar el sitio

Como se mencionó, creo que hay una mejor manera, así que si alguien tiene algunos consejos, por favor comparta. ¡Gracias!