Vous devez mettre à jour manuellement les données en cas d'incohérence des données ou lorsque vous souhaitez modifier la valeur d'une colonne existante. Les mises à jour manuelles doivent être effectuées avec prudence, car vous travaillerez directement avec les données de production.
Cette fois, je vais vous montrer comment mettre à jour en toute sécurité et manuellement les données de l'application Ruby on Rails.
Par exemple, supposons qu'une incohérence de données se produise entre l'événement et l'entrée liés de manière un-à-plusieurs et qu'il devienne nécessaire de changer manuellement l'entrée liée à ʻevent_id = 10 en ʻevent_id = 11
. Je vais.
Une solution de contournement courante consiste à mettre à jour manuellement avec la console rails
comme suit:
#Confirmation avant la mise à jour
Entry.where(event_id: 10).count
=> 5
Entry.where(event_id: 11).count
=> 0
#Mettre à jour le travail
Entry.where(event_id: 10).update_all(event_id: 11)
#Confirmation après mise à jour
Entry.where(event_id: 10).count
=> 0
Entry.where(event_id: 11).count
=> 5
Lors de la mise à jour des données avec rails console
, je pense que le processus" d'exécution de commandes dans l'environnement de développement et de confirmation qu'il n'y a pas d'erreurs avant d'effectuer le travail de production "est souvent adopté.
Si le nombre de données est petit ou si la mise à jour des données n'est pas compliquée, la mise à jour manuelle à l'aide de rails console
convient.
Cependant, ** Lors de la mise à jour de données compliquées, je souhaite pouvoir revenir à l'état d'avant la mise à jour s'il y a un problème **.
Dans un tel cas, il est recommandé de mettre à jour les données à l'aide de transactions.
Insérez la mise à jour des données dans nom du modèle.transaction
afin que la restauration puisse être effectuée en cas de problèmes.
La restauration est effectuée lorsqu'une exception se produit dans la transaction.
Vous pouvez utiliser rise ActiveRecord :: Rollback
pour déclencher intentionnellement une exception, ce qui entraîne une annulation.
Le script qui exécute la mise à jour manuelle des données introduite précédemment dans une transaction est le suivant.
# app/script/maintenance/20201103_fix_envent_id.rb
ActiveRecord::Base.transaction do
# update_Empêcher la mise à jour de l'horodatage at
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 'échec de la mise à jour de l'entrée'
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
#Puisque je l'ai mis à faux au début, retournez-le à l'original (vrai)
Entry.record_timestamps = true
end
Le but du script est qu'il attend l'entrée de la commande en utilisant gets
une fois la mise à jour des données terminée.
Si vous entrez un caractère autre que «yes», «raise ActiveRecord :: Rollback» sera appelé et le rollback sera effectué.
En sortant l'état de l'enregistrement le cas échéant, par exemple la manière dont le nombre d'enregistrements a changé avant et après la mise à jour des données, vous pouvez vérifier en toute sécurité qu'il n'y a pas de problèmes avant de terminer la mise à jour des données.
Exécutez le script avec rails runner
.
Cette fois, j'exécute «rails runner» contre l'environnement de développement. Ajoutez l'option -e production
si vous souhaitez l'exécuter dans un environnement de production.
$ 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
Les applications Rails ont plusieurs méthodes pour mettre à jour les données. Les différences entre les méthodes typiques sont les suivantes.
Méthode | Validation | Rappeler | updated_mise à jour de à | S'il faut mettre à jour plusieurs colonnes |
---|---|---|---|---|
update | ○ | ○ | ○ | ○ |
update_attributes | ○ | ○ | ○ | ○ |
update_attribute | × | ○ | ○ | × |
update_all | × | × | × | ○ |
update_columns | × | × | × | ○ |
update_column | × | × | × | × |
** Si vous voulez juste changer la valeur de l'enregistrement, utilisez ʻupdate_columns, et si vous voulez mettre à jour les données tout en assurant la cohérence, utilisez ʻupdate
**.
De plus, lors de la mise à jour des données avec ʻupdate, si vous avez des problèmes si ʻupdated_at
de l'enregistrement à mettre à jour change, il est préférable de définirrecord_timestamps
sur false
avant la mise à jour. N'oubliez pas de remettre record_timestamps
à true
après la mise à jour.
Ceci conclut l'introduction de méthodes de mise à jour des données utilisant des transactions.
--Si vous souhaitez mettre à jour les données en toute sécurité, il est recommandé d'exécuter le script inclus dans la transaction avec rails runner.
Je fais Twitter (@ nishina555). J'espère que vous me suivrez!