Ich habe eine Tabelle in einer Rails-App mit Hunderttausenden von Datensätzen, und sie haben nur einen created_at
Zeitstempel. Ich füge die Möglichkeit hinzu, diese Datensätze zu bearbeiten, daher möchte ich updated_at
der Tabelle einen Zeitstempel hinzufügen . Bei meiner Migration zum Hinzufügen der Spalte möchte ich alle Zeilen aktualisieren, damit die neuen updated_at
mit den alten übereinstimmen created_at
, da dies die Standardeinstellung für neu erstellte Zeilen in Rails ist. Ich könnte ein find(:all)
und die Datensätze durchlaufen, aber das würde wegen der Größe der Tabelle Stunden dauern. Was ich wirklich tun möchte ist:
UPDATE table_name SET updated_at = created_at;
Gibt es eine bessere Möglichkeit, dies bei einer Rails-Migration mit ActiveRecord zu tun, als Raw SQL auszuführen?
Yourmodel.update_all 'update_at=created_at'
ist schöner, nein? Es funktioniert auch in einem Bereich.up
gefolgt von einemdown
ausführen . " Alsodef change
nur stattdessen überlegen .change
Methode noch nicht, aber in diesem Fall bevorzuge ich es immer noch, explizit zu verwendenup
und expliziterdown
zu sein (wenn Sie steuern möchten, was dasdown
tun soll).Sie können update_all verwenden, das sehr ähnlich zu Raw SQL funktioniert. Das sind alles Möglichkeiten, die Sie haben.
Übrigens schenke ich Migrationen nicht so viel Aufmerksamkeit. Manchmal ist Raw SQL wirklich die beste Lösung. Im Allgemeinen wird Migrationscode nicht wiederverwendet. Dies ist eine einmalige Aktion, daher kümmere ich mich nicht um die Reinheit des Codes.
quelle
update_all
innerhalb der Migrationsdatei :-) Sie können auch Roh-SQL innerhalb der Migrationsdatei ausführen. Istupdate_all
aber etwas eleganter. Beide werden genau die gleiche Leistung erbringen.update_all
ich keine Ahnung, wie man einen Wert der Spalte auf den eines anderen setzt, wie es das OP verlangt. Bitte demonstrieren Sie.Wie Gregdan schrieb, können Sie verwenden
update_all
. Sie können so etwas tun:Model.where(...).update_all('updated_at = created_at')
Der erste Teil ist Ihr typischer Satz von Bedingungen. Der letzte Teil beschreibt, wie die Zuweisungen vorgenommen werden. Dies ergibt
UPDATE
zumindest in Rails 4 eine Aussage.quelle
SET'posts'.'email' = 'options'
, die Optionen ist eine wörtliche ZeichenfolgeUser.update_all('updated_at = created_at')
SQL (0.4ms) UPDATE "users" SET updated_at = created_at
Sie können den folgenden Befehl direkt auf Ihrem ausführen
rails console
ActiveRecord::Base.connection.execute("UPDATE TABLE_NAME SET COL2 = COL1")
Beispiel: Ich möchte die SKU meiner Elementtabelle mit remote_id der Elementtabellen aktualisieren. Der Befehl lautet wie folgt:
ActiveRecord::Base.connection.execute("UPDATE items SET sku = remote_id")
quelle
Yourmodel
bereits gelöscht werden kann. Versuchen Sie, die Verwendung von Modellen in Migrationen zu vermeiden.Dies ist eine allgemeine Methode zum Lösen, ohne dass eine Abfrage geschrieben werden muss, da Abfragen einem Risiko ausgesetzt sind.
class Demo < ActiveRecord::Migration def change add_column :events, :time_zone, :string Test.all.each do |p| p.update_attributes(time_zone: p.check.last.time_zone) end remove_column :sessions, :time_zone end end
quelle
Als einmalige Operation würde ich es einfach in der machen
rails console
. Wird es wirklich Stunden dauern? Vielleicht, wenn es Millionen von Datensätzen gibt ...records = ModelName.all; records do |r|; r.update_attributes(:updated_at => r.created_at); r.save!; end;`
quelle