[RUBY] Verhindern Sie Vorgänge! Sichere manuelle Datenaktualisierungsmethode für Rails mithilfe von Transaktionen

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.

Allgemeine manuelle Datenaktualisierungsmethode

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.

Hier vorgestellte Methode: Daten innerhalb einer Transaktion aktualisieren

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

Referenz: Zusammenfassung der Aktualisierungsmethoden für Rails-Anwendungen

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.

Zusammenfassung

Damit ist die Einführung von Datenaktualisierungsmethoden unter Verwendung von Transaktionen abgeschlossen.

Ich mache Twitter (@ nishina555). Ich hoffe du folgst mir!

Referenz

Recommended Posts

Verhindern Sie Vorgänge! Sichere manuelle Datenaktualisierungsmethode für Rails mithilfe von Transaktionen
[Schienen] So verhindern Sie den Bildschirmübergang
[Rails] So laden Sie Bilder mit Carrierwave hoch
So implementieren Sie die Image-Veröffentlichung mithilfe von Schienen
[Rails] So laden Sie mehrere Bilder mit Carrierwave hoch
Wie schreibe ich Rails
So deinstallieren Sie Rails
So generieren Sie manuell ein JWT mit Knock in Rails
Festlegen von Umgebungsvariablen bei Verwendung von Payjp mit Rails
[Rails] Verwendung von Enum
Wie man Schienenrouten liest
Verwendung von Rails Join
Festlegen und Beschreiben von Umgebungsvariablen mit Rails zsh
So aktualisieren Sie mit activerecord-import
So stellen Sie jQuery in Rails-Apps mit Webpacker bereit
So beenden Sie den Rails-Server
Wie schreibe ich Rails Seed
[Rails] Verwendung der Validierung
[Schienen] So deaktivieren Sie Turbolinks
[Rails] So verwenden Sie authenticate_user!
[Rails] So implementieren Sie Scraping
[Schienen] Wie man Samen macht
Wie schreibe ich Rails Routing
[Rails] So installieren Sie simple_calendar
[Rails] So installieren Sie reCAPTCHA
[Schienen] Verwendung von Scope
So autorisieren Sie mit graphql-ruby
So steuern Sie Transaktionen in Spring Boot ohne Verwendung von @Transactional
So verhindern Sie, dass vergangene Daten in Rails-Formularen eingegeben werden
[Rails 6] So erstellen Sie mit cocoon einen dynamischen Formular-Eingabebildschirm
[Rails] So laden Sie Bilder mit Carrierwave und Fog-Aws in AWS S3 hoch
[Rails] So laden Sie Bilder mit refile und refile-s3 in AWS S3 hoch
[Rails 5] Anzeigen des Bildschirms zum Ändern des Kennworts bei Verwendung von devise
[rails6.0.0] Speichern von Bildern mit Active Storage im Assistentenformat
[Rails] Wie man Edelstein "devise" benutzt
[Schienen] Verwendung von Geräten (Hinweis)
[Rails] Verwendung von Flash-Nachrichten
[Rails] Anzeigen von Datenbankinformationen
Verwendung von Ruby on Rails
So stellen Sie Bootstrap auf Rails bereit
[Rails] So beschleunigen Sie das Docker-Compose
[Schienen] So fügen Sie neue Seiten hinzu
[Rails] Wie schreibe ich eine Ausnahmebehandlung?
[Rails] So installieren Sie ImageMagick (RMajick)
[Rails] So installieren Sie Font Awesome
[Rails] Verwendung von Active Storage
So installieren Sie jQuery in Rails 6
[Rails] So implementieren Sie die Sternebewertung