Batch migration due to sites having > 200k rows of solved

This commit is contained in:
Nat 2025-03-19 14:33:32 +08:00
parent 9c583d5df4
commit e5699590ea
No known key found for this signature in database
GPG Key ID: 4938B35D927EC773
1 changed files with 39 additions and 24 deletions

View File

@ -1,38 +1,53 @@
# frozen_string_literal: true # frozen_string_literal: true
# #
class CopySolvedTopicCustomFieldToDiscourseSolvedTopics < ActiveRecord::Migration[7.2] class CopySolvedTopicCustomFieldToDiscourseSolvedTopics < ActiveRecord::Migration[7.2]
disable_ddl_transaction!
BATCH_SIZE = 5000
def up def up
create_table :discourse_solved_topics do |t| create_table :discourse_solved_topics do |t|
t.integer :topic_id, null: false t.integer :topic_id, null: false
t.integer :answer_post_id, null: false t.integer :answer_post_id, null: false
t.integer :accepter_user_id t.integer :accepter_user_id, null: false
t.integer :topic_timer_id t.integer :topic_timer_id
t.timestamps t.timestamps
end end
execute <<-SQL last_id = 0
INSERT INTO discourse_solved_topics ( loop do
topic_id, rows = DB.query(<<~SQL, last_id: last_id, batch_size: BATCH_SIZE)
answer_post_id, INSERT INTO discourse_solved_topics (
topic_timer_id, topic_id,
accepter_user_id, answer_post_id,
created_at, topic_timer_id,
updated_at accepter_user_id,
) SELECT DISTINCT created_at,
tc.topic_id, updated_at
CAST(tc.value AS INTEGER), )
CAST(tc2.value AS INTEGER), SELECT DISTINCT ON (tc.topic_id)
ua.acting_user_id, tc.topic_id,
tc.created_at, CAST(tc.value AS INTEGER),
tc.updated_at CAST(tc2.value AS INTEGER),
FROM topic_custom_fields tc COALESCE(ua.acting_user_id, -1),
LEFT JOIN topic_custom_fields tc2 tc.created_at,
ON tc2.topic_id = tc.topic_id AND tc2.name = 'solved_auto_close_topic_timer_id' tc.updated_at
LEFT JOIN user_actions ua FROM topic_custom_fields tc
ON ua.target_topic_id = tc.topic_id LEFT JOIN topic_custom_fields tc2
WHERE tc.name = 'accepted_answer_post_id' ON tc2.topic_id = tc.topic_id
AND ua.action_type = #{UserAction::SOLVED} AND tc2.name = 'solved_auto_close_topic_timer_id'
SQL LEFT JOIN user_actions ua
ON ua.target_topic_id = tc.topic_id
AND ua.action_type = #{UserAction::SOLVED}
WHERE tc.name = 'accepted_answer_post_id'
AND tc.id > :last_id
ORDER BY tc.topic_id, ua.created_at DESC
LIMIT :batch_size
SQL
break if rows.length == 0
last_id += BATCH_SIZE
end
end end
def down def down