Ok ich habe es durch. Ich denke, es gibt einen schnelleren Weg, die Mongo-Konsole mit so etwas zu verwenden:Feldtyp">MongoDB:Wie ändere ich den Feldtyp?
Aber ich konnte die Konvertierung nicht zum Laufen bringen, also entschied ich mich für diese langsamere Methode in der Rails-Konsole mit mehr Ausfallzeit. Wenn jemand eine schnellere Lösung hat, poste sie bitte.
- Erstellen Sie ein neues Integer-Feld mit einem neuen Namen, sagen Sie
amount2
- wandeln Sie jeden
amount
um auf den richtigen Wert füramount2
in einer Konsolen- oder Rake-Aufgabe
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
Beachten Sie, dass .all.each wegen Mongodb-Cursors gut funktioniert (Sie müssen .find_each oder .find_in_batches nicht wie normales ActiveRecord mit MySQL verwenden). Es wird keinen Speicher füllen, solange die identity_map ausgeschaltet ist.
-
Nehmen Sie die Website zur Wartung herunter, führen Sie die Migration noch einmal aus, um alle Betragsfelder zu erfassen, die sich in den letzten Minuten geändert haben könnten (etwas wie
Transaction.where(:updated_at.gt => 1.hour.ago).each_with_index...
-
kommentieren Sie
field :amount, type: BigDecimal
in Ihrem Modell möchten Sie nicht, dass Mongoid mehr über dieses Feld erfährt, und geben Sie diesen Code ein - Führen Sie jetzt ein anderes Skript aus, um Ihre Spalte umzubenennen (es überschreibt dabei alle alten BigDecimal-String-Werte). Möglicherweise müssen Sie alle Validierungen kommentieren, die Sie für das Modell haben, die das alte Feld erwarten.
Mongoid.identity_map_enabled = false
Transaction.all.each_with_index do |t,i|
puts i if i%1000==0
t.rename :amount2, :amount
end
Dies ist atomar und erfordert kein Speichern des Modells.
- Aktualisieren Sie Ihr Modell, um den neuen Spaltentyp
field :amount, type: Integer
widerzuspiegeln - Bereitstellen und Wiederherstellen der Website
Wie bereits erwähnt, denke ich, dass es einen besseren Weg gibt, also wenn jemand ein paar Tipps hat, bitte teilen. Danke!