#postgresql #ruby-on-rails-4 #activerecord
#postgresql #ruby-on-rails-4 #activerecord
Вопрос:
Допустим, у меня есть 20 таблиц, и в каждой таблице есть столбец, updated_at
я хочу обновить все строки во всех таблицах, например, updated_at
размер столбца каждой строки должен увеличиться на 1 час.
Как я могу это сделать, избегая обновления объекта active records, я бы предпочел вместо этого запускать SQL-запрос к каждой таблице по одному запросу для одной таблицы.
Ответ №1:
Если вы зададите этот вопрос в разделе администратора базы данных SO, я думаю, вы получите гораздо лучший ответ.
Я попробовал поискать в Google и могу найти:
https://www.w3schools.com/sql/func_sqlserver_dateadd.asp
ВЫБЕРИТЕ DATEADD(месяц, 2, ‘08.08.2017 25’) В КАЧЕСТВЕ DateAdd;
Итак, в вашем случае, если он называется updated_at, а таблица — users:
SELECT UpdatedAt, DATEADD(hour, 1, UpdatedAt) AS DateAdd FROM Employees;
Я довольно хреново разбираюсь в SQL, но я думаю, что это должно иметь смысл.
Если это не сработает, опубликуйте это в разделе database, и вам помогут люди, которые знают, о чем они говорят 🙂
Комментарии:
1. postgresql не предоставляет функцию DATEADD.
Ответ №2:
Вы можете выполнить это с помощью консоли Rails, фактически не создавая ActiveRecord
объекты, если вы используете update_columns
Вы должны быть в состоянии сделать:
YourThing.find_each do |thing|
new_time = thing.updated_at 1.hour
thing.update_columns(updated_at: new_time)
end
Это позволит обойти проверку и все обратные вызовы, поэтому оно должно выполняться довольно быстро, в зависимости от количества записей, с которыми вы работаете.
Вот документация для update_columns
: https://apidock.com/rails/ActiveRecord/Persistence/update_columns
Комментарии:
1. Спасибо! но у меня есть идея
update_column
, но потребуется выполнять цикл для каждой записи, а у меня миллиарды записей, и для завершения такого подхода потребуется слишком много времени.
Ответ №3:
просто чтобы помочь другим, вот как я смог решить эту проблему
ActiveRecord::Base.connection.execute("UPDATE users SET created_at = created_at INTERVAL '3600 seconds'")