MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

Ändern Sie den Feldtyp in Mongoid, ohne Daten zu verlieren

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ür amount2 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!