Sie müssen die Daten manuell aktualisieren, wenn Daten inkonsistent sind oder wenn Sie den Wert einer vorhandenen Spalte ändern möchten. Manuelle Aktualisierungen sollten mit Vorsicht durchgeführt werden, da Sie direkt mit den Produktionsdaten arbeiten.
Dieses Mal werde ich Ihnen zeigen, wie Sie die Daten der Ruby on Rails-Anwendung sicher und manuell aktualisieren können.
Angenommen, es tritt eine Dateninkonsistenz zwischen Ereignis und Eintrag auf, die eins zu viele verknüpft sind, und es wird erforderlich, den mit "event_id = 10" verknüpften Eintrag manuell in "event_id = 11" zu ändern. Ich werde.
Eine übliche Problemumgehung besteht darin, manuell mit der "Rails-Konsole" wie folgt zu aktualisieren:
#Bestätigung vor dem Update
Entry.where(event_id: 10).count
=> 5
Entry.where(event_id: 11).count
=> 0
#Arbeit aktualisieren
Entry.where(event_id: 10).update_all(event_id: 11)
#Bestätigung nach dem Update
Entry.where(event_id: 10).count
=> 0
Entry.where(event_id: 11).count
=> 5
Beim Aktualisieren von Daten mit der "Rails-Konsole" wird häufig der Prozess "Ausführen von Befehlen in der Entwicklungsumgebung und Bestätigen, dass keine Fehler vorliegen, bevor die eigentliche Arbeit ausgeführt wird" angewendet.
Wenn die Anzahl der Daten gering ist oder die Datenaktualisierung nicht kompliziert ist, ist eine manuelle Aktualisierung über die Schienenkonsole in Ordnung. ** Beim Aktualisieren komplizierter Daten möchte ich jedoch in der Lage sein, vor dem Update in den Status zurückzukehren, wenn ein Problem auftritt **. In einem solchen Fall wird empfohlen, die Daten mithilfe von Transaktionen zu aktualisieren.
Fügen Sie die Datenaktualisierung in model name.transaction
ein, damit bei Problemen ein Rollback durchgeführt werden kann.
Ein Rollback wird durchgeführt, wenn innerhalb der Transaktion eine Ausnahme auftritt. Sie können "Raise ActiveRecord :: Rollback" verwenden, um absichtlich eine Ausnahme auszulösen, die zu einem Rollback führt.
Das Skript, das die zuvor in einer Transaktion eingeführte manuelle Datenaktualisierung ausführt, lautet wie folgt.
# app/script/maintenance/20201103_fix_envent_id.rb
ActiveRecord::Base.transaction do
# update_Verhindern Sie, dass der Zeitstempel aktualisiert wird
Entry.record_timestamps = false
puts "Before event_id = 10: #{Entry.where(event_id: 10).count}"
puts "Before event_id = 11: #{Entry.where(event_id: 11).count}"
Entry.where(event_id: 10).each do |entry|
begin
entry.update!(event_id: 11)
rescue => e
puts 'Eintragsaktualisierungsfehler'
puts e
puts "entry.id: #{entry.id}"
end
end
puts "After entry_id = 10: #{Entry.where(event_id: 10).count}"
puts "After entry_id = 11: #{Entry.where(event_id: 11).count}"
print "Are you sure?(yes/no) > "
answer = gets.strip
if answer == "yes"
puts "committed"
else
puts "rollback"
raise ActiveRecord::Rollback
end
#Da ich es am Anfang auf false gesetzt habe, kehre zum Original zurück (true).
Entry.record_timestamps = true
end
Der Punkt des Skripts besteht darin, dass es nach Abschluss der Datenaktualisierung mit "get" auf die Eingabe des Befehls wartet. Wenn Sie ein anderes Zeichen als "Ja" eingeben, wird "Raise ActiveRecord :: Rollback" aufgerufen und ein Rollback durchgeführt.
Indem Sie den Datensatzstatus entsprechend ausgeben, z. B. wie sich die Anzahl der Datensätze vor und nach der Datenaktualisierung geändert hat, können Sie sicher überprüfen, dass keine Probleme vorliegen, und die Datenaktualisierung dann sicher abschließen.
Führen Sie das Skript mit "Rails Runner" aus. Dieses Mal starte ich "Rails Runner" gegen die Entwicklungsumgebung. Fügen Sie die Option "-e Produktion" hinzu, wenn Sie sie in einer Produktionsumgebung ausführen möchten.
$ rails runner app/script/maintenance/20201103_fix_envent_id.rb
Before Entry.where(event_id: 10).count: 5
Before Entry.where(event_id: 11).count: 0
After Entry.where(event_id: 10).count: 0
After Entry.where(event_id: 11).count: 5
Are you sure?(yes/no) > yes
committed
Rails-Anwendungen verfügen über mehrere Methoden zum Aktualisieren von Daten. Die Unterschiede zwischen typischen Methoden sind wie folgt.
Methode | Validierung | Rückrufen | updated_Update von at | Gibt an, ob mehrere Spalten aktualisiert werden sollen |
---|---|---|---|---|
update | ○ | ○ | ○ | ○ |
update_attributes | ○ | ○ | ○ | ○ |
update_attribute | × | ○ | ○ | × |
update_all | × | × | × | ○ |
update_columns | × | × | × | ○ |
update_column | × | × | × | × |
** Wenn Sie nur den Wert des Datensatzes ändern möchten, verwenden Sie "update_columns". Wenn Sie die Daten aktualisieren und gleichzeitig die Konsistenz sicherstellen möchten, verwenden Sie "update" **.
Wenn Sie beim Aktualisieren von Daten mit "update" Probleme haben, wenn sich das "update_at" des zu aktualisierenden Datensatzes ändert, ist es besser, "record_timestamps" vor dem Aktualisieren auf "false" zu setzen. Vergessen Sie nicht, record_timestamps
nach dem Update wieder auf true
zu setzen.
Damit ist die Einführung von Datenaktualisierungsmethoden unter Verwendung von Transaktionen abgeschlossen.
Ich mache Twitter (@ nishina555). Ich hoffe du folgst mir!
Recommended Posts