Ok, zvládl jsem to. Myslím, že existuje rychlejší způsob použití mongo konzole s něčím takovým:MongoDB:Jak změnit typ pole?
Ale nemohl jsem zprovoznit konverzi, takže jsem se rozhodl pro tuto pomalejší metodu v konzole rails s delšími prostoji. Pokud má někdo rychlejší řešení, pošlete ho.
- vytvořte nové pole Integer s novým názvem, řekněte
amount2
- převést každou
amount
na správnou hodnotu proamount2
v úloze konzole nebo 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
Všimněte si, že .all.each funguje dobře (nemusíte používat .find_each nebo .find_in_batches jako běžný activerecord s mysql) kvůli mongodb kurzorům. Dokud je identita_map vypnutá, nezaplní paměť.
-
sundejte web z důvodu údržby, spusťte migraci ještě jednou, abyste zachytili všechna pole množství, která se mohla v posledních několika minutách změnit (něco jako
Transaction.where(:updated_at.gt => 1.hour.ago).each_with_index...
-
komentovat
field :amount, type: BigDecimal
ve vašem modelu už nechcete, aby mongoid věděl o tomto poli, a vložte tento kód - nyní spusťte další skript pro přejmenování sloupce (přepíše všechny staré hodnoty řetězce BigDecimal v procesu). Možná budete muset okomentovat všechna ověření modelu, která očekávají staré pole.
Mongoid.identity_map_enabled = false
Transaction.all.each_with_index do |t,i|
puts i if i%1000==0
t.rename :amount2, :amount
end
Toto je atomické a nevyžaduje uložení modelu.
- aktualizujte svůj model tak, aby odrážel nový typ sloupce
field :amount, type: Integer
- nasadit a obnovit web
Jak již bylo zmíněno, myslím, že existuje lepší způsob, takže pokud má někdo nějaké tipy, podělte se. Díky!