Добре, успях. Мисля, че има по-бърз начин за използване на mongo конзолата с нещо подобно:MongoDB:Как да промените типа на поле?
Но не можах да накарам преобразуването да работи, така че избрах този по-бавен метод в rails конзолата с повече време на престой. Ако някой има по-бързо решение, моля, публикувайте го.
- създайте ново поле Integer с ново име, да кажем
amount2
- конвертирайте всяка
amount
към правилната стойност заamount2
в конзола или рейк задача
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
Имайте предвид, че .all.each работи добре (не е необходимо да използвате .find_each или .find_in_batches като обикновен активен запис с mysql) поради курсорите на mongodb. Няма да запълни паметта, докато identity_map е изключена.
-
извадете сайта за поддръжка, стартирайте миграцията още веднъж, за да заснемете всички полета за суми, които може да са се променили през последните няколко минути (нещо като
Transaction.where(:updated_at.gt => 1.hour.ago).each_with_index...
-
коментирайте
field :amount, type: BigDecimal
във вашия модел не искате mongoid да знае повече за това поле и натиснете този код - сега изпълнете друг скрипт, за да преименувате вашата колона (той презаписва всички стари стойности на низове BigDecimal в процеса). Може да се наложи да коментирате всички проверки, които имате на модела, които очакват старото поле.
Mongoid.identity_map_enabled = false
Transaction.all.each_with_index do |t,i|
puts i if i%1000==0
t.rename :amount2, :amount
end
Това е атомно и не изисква запазване на модела.
- актуализирайте модела си, за да отразява новия тип колона
field :amount, type: Integer
- разположете и възстановете сайта
Както споменах, мисля, че има по-добър начин, така че ако някой има съвети, моля, споделете. Благодаря!