Discourse Retort

음, 결국 일이 벌어졌네요. retort 플러그인 때문에 discourse를 업데이트할 수 없었습니다.

다음과 같은 데이터베이스 마이그레이션 오류가 발생했습니다:

could not create unique index "index_post_details_on_post_id_and_key_ccnew_ccnew"                                                 DETAIL:  Key (post_id, key)=(30297, +1|retort) is duplicated.

저는 이 스크립트를 기반으로 자체 마이그레이션 코드를 작성했습니다. 제가 수행한 작업은 다음과 같습니다.

  • discourse를 다시 작동시키기 위해 템플릿 .yml 파일의 "version"을 discourse 저장소에서 약 2주 전 커밋으로 덮어써야 했습니다.
  • reactions 플러그인을 추가하여 사이트를 다시 빌드하여 복구했습니다.
  • reactions 플러그인을 retort와 동일한 리액션 세트로 구성했습니다. '좋아요’로 해석될 수 있는 리액션은 사용하지 않았습니다.
  • @mcdanlj의 스크립트를 약간 수정하여 다음 단계들을 따랐습니다 (모든 retort를 마이그레이션하고 싶었으며, retort와 리액션 사이에 이미 1:1 매핑이 있었기 때문):
  • ./launcher enter app 실행
  • rails c 실행
  • 아래 코드를 붙여넣으세요 (rails 콘솔이 잘못된 줄바꿈으로 코드를 다시 출력하는 것 같습니다. 이중 줄바꿈을 추가했지만 출력에는 큰 차이가 없었습니다. 만약 아래 코드에서 구문 오류가 발생하면 각 줄 뒤에 한 줄을 더 추가하세요):
def migrateRetortToReactions()
  retort = "retort".freeze
  emojiType = "emoji".freeze
  usermap = Hash.new { |hash, username| hash[username] = User.find_by_username(username) }
  postmap = Hash.new { |hash, post_id| hash[post_id] = Post.find(post_id) }
  likeType = PostActionType.where(name_key: "like").pluck(:id).first
  PostDetail.where(extra: retort).each do |pd|
    begin
      p = postmap[pd.post_id]
    rescue
      # PostDetail not consistent WRT delete
      $stderr.puts sprintf("Could not find post for %d: %s / %s", pd.post_id, pd.key, pd.value)
      next
    end

    emoji = pd.key.split('|').first
    users = JSON.parse(pd.value)
    users.each do |user|
      u = usermap[user]
      next if u.nil? # changed user name or deleted user leaves orphaned Retorts
      e = emoji
      r = DiscourseReactions::Reaction.where(post_id: p.id, reaction_type: emojiType, reaction_value: e).first_or_create
      ru = DiscourseReactions::ReactionUser.where(user_id: u.id, post_id: p.id).first
      next unless ru.nil?
      $stderr.puts sprintf("Converting Retort %s to Reaction %s for user %s in %s", emoji, e, user, p.url)
      DiscourseReactions::ReactionUser.create(reaction_id: r.id, user_id: u.id, post_id: p.id, created_at: pd.created_at)
    end
  end
end
  • 이 시점에서 혹시 모르도록 사이트 백업을 만들었습니다.
  • 그런 다음 migrateRetortToReactions를 실행하세요. 시간이 좀 걸릴 수 있습니다. 제 경우엔 문제를 보거나 겪지 않았습니다. 실행 후 콘솔에 변경된 모든 객체가 표시되는 것 같으니 q를 눌러 종료하세요.
  • 이제 사이트에서 데이터가 올바르게 마이그레이션되었어야 합니다.
  • 마지막 단계로 PostDetail.where(extra: "retort").destroy_all을 실행하여 retort 데이터를 삭제해야 합니다.
  • 이제 최신 discourse 버전으로 retort 플러그인 없이 사이트를 다시 빌드할 수 있었습니다.

결국 마이그레이션은 그렇게 어렵지 않았지만 꽤 무서웠습니다. 그리고 이전에 논의했듯이, 같은 사용자가 좋아요와 retort를 모두 달았던 게시물에서는 리액션이 좋아요를 덮어쓰게 됩니다.

6개의 좋아요