Ok, udało mi się. Myślę, że jest szybszy sposób korzystania z konsoli mongo z czymś takim:MongoDB:Jak zmienić typ pola?
Ale nie mogłem uruchomić konwersji, więc zdecydowałem się na tę wolniejszą metodę w konsoli rails z dłuższymi przestojami. Jeśli ktoś ma szybsze rozwiązanie, opublikuj je.
- utwórz nowe pole Integer z nową nazwą, powiedz
amount2
- przekonwertuj każdą
amount
do właściwej wartości dlaamount2
w konsoli lub zadaniu prowizji
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
Zauważ, że .all.each działa dobrze (nie musisz używać .find_each lub .find_in_batches jak zwykły activerecord z mysql) z powodu kursorów mongodb. Nie zapełni pamięci, dopóki mapa tożsamości jest wyłączona.
-
wyłącz witrynę w celu konserwacji, uruchom migrację jeszcze raz, aby przechwycić dowolną ilość pól, które mogły ulec zmianie w ciągu ostatnich kilku minut (coś w rodzaju
Transaction.where(:updated_at.gt => 1.hour.ago).each_with_index...
-
wykomentuj
field :amount, type: BigDecimal
w twoim modelu nie chcesz, aby mongoid więcej wiedział o tym polu i wciśnij ten kod - teraz uruchom kolejny skrypt, aby zmienić nazwę kolumny (zastępuje on wszystkie stare wartości ciągu znaków BigDecimal w procesie). Być może będziesz musiał skomentować wszelkie walidacje, które masz w modelu, które oczekują starego pola.
Mongoid.identity_map_enabled = false
Transaction.all.each_with_index do |t,i|
puts i if i%1000==0
t.rename :amount2, :amount
end
To jest atomowe i nie wymaga zapisywania w modelu.
- zaktualizuj swój model, aby odzwierciedlić nowy typ kolumny
field :amount, type: Integer
- wdróż i przywróć witrynę
Jak wspomniałem, myślę, że jest lepszy sposób, więc jeśli ktoś ma jakieś wskazówki, podziel się nimi. Dzięki!