FIX: Migration was only done for first batch (#344)

https://github.com/discourse/discourse-solved/pull/342 was deployed and observed to only have 5000 (batch size) migrated. This is an error in migration where the ids had a gap between the batch.

This PR changes the migration to just loop through all topic custom fields with each loop increasing by batch size.
This commit is contained in:
Natalie Tay 2025-03-25 17:06:22 +08:00 committed by GitHub
parent 55c1eb4d60
commit e0a579e69e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 66 additions and 6 deletions

View File

@ -3,12 +3,18 @@
class CopySolvedTopicCustomFieldToDiscourseSolvedSolvedTopics < ActiveRecord::Migration[7.2]
disable_ddl_transaction!
BATCH_SIZE = 5000
BATCH_SIZE = 10_000
def up
max_id =
DB.query_single(
"SELECT MAX(id) FROM topic_custom_fields WHERE topic_custom_fields.name = 'accepted_answer_post_id'",
).first
return unless max_id
last_id = 0
loop do
rows = DB.query(<<~SQL, last_id: last_id, batch_size: BATCH_SIZE)
while last_id < max_id
DB.exec(<<~SQL, last_id: last_id, batch_size: BATCH_SIZE)
INSERT INTO discourse_solved_solved_topics (
topic_id,
answer_post_id,
@ -33,11 +39,10 @@ class CopySolvedTopicCustomFieldToDiscourseSolvedSolvedTopics < ActiveRecord::Mi
AND ua.action_type = 15
WHERE tc.name = 'accepted_answer_post_id'
AND tc.id > :last_id
ORDER BY tc.topic_id, ua.created_at DESC
LIMIT :batch_size
AND tc.id <= :last_id + :batch_size
ON CONFLICT DO NOTHING
SQL
break if rows.length == 0
last_id += BATCH_SIZE
end
end

View File

@ -0,0 +1,55 @@
# frozen_string_literal: true
#
class CopyRemainingSolvedTopicCustomFieldToDiscourseSolvedSolvedTopics < ActiveRecord::Migration[
7.2
]
disable_ddl_transaction!
BATCH_SIZE = 5000
def up
max_id =
DB.query_single(
"SELECT MAX(id) FROM topic_custom_fields WHERE topic_custom_fields.name = 'accepted_answer_post_id'",
).first
return unless max_id
last_id = 0
while last_id < max_id
DB.exec(<<~SQL, last_id: last_id, batch_size: BATCH_SIZE)
INSERT INTO discourse_solved_solved_topics (
topic_id,
answer_post_id,
topic_timer_id,
accepter_user_id,
created_at,
updated_at
)
SELECT DISTINCT ON (tc.topic_id)
tc.topic_id,
CAST(tc.value AS INTEGER),
CAST(tc2.value AS INTEGER),
COALESCE(ua.acting_user_id, -1),
tc.created_at,
tc.updated_at
FROM topic_custom_fields tc
LEFT JOIN topic_custom_fields tc2
ON tc2.topic_id = tc.topic_id
AND tc2.name = 'solved_auto_close_topic_timer_id'
LEFT JOIN user_actions ua
ON ua.target_topic_id = tc.topic_id
AND ua.action_type = 15
WHERE tc.name = 'accepted_answer_post_id'
AND tc.id > :last_id
AND tc.id <= :last_id + :batch_size
ON CONFLICT DO NOTHING
SQL
last_id += BATCH_SIZE
end
end
def down
raise ActiveRecord::IrreversibleMigration
end
end