大規模Drupalフォーラム移行、インポータエラーと制限

ああ…本番データでインポーターを複数回実行することになるとは思いもよりませんでした。そのアイデア、本当にありがとうございます。

基本的に、本番のDrupalデータベースをダンプし、インポーターが完了するまで(どれくらい時間がかかるにしても)公開したままにしておき、その後Drupalフォーラムをオフラインモードにして、別のデータベースダンプを行い、それをインポーターのMySQLインスタンスにロードしてインポータースクリプトを再実行するということでしょうか?

そこで考えられる唯一の欠点は、最初のインポートから2回目のインポートまでの間(仮に3日間としましょう)に行われたDrupalの投稿の編集や投稿の_削除_、既存のユーザープロフィールの変更はインポートされず、その間に作成された完全に新しいユーザーと投稿のみがインポートされる、ということですよね?

その通りです。編集されたデータは失われます。代替案は、その間フォーラムをオフラインにすることです。人々を警告することはできます。実際には誰も文句を言った人はいません。

「いいね!」 1

クール、それはダウンタイムを最小限に抑えるためのかなり合理的な妥協案のように聞こえます。アイデアをもう一度ありがとう。

「いいね!」 1

最終的な本番インポートを実行すると決めた直後に、インポートされたフォーラムスレッドをいくつかランダムにチェックしていたところ、大きな問題を発見しました。ここでも繰り返しテーマとなっているように、これはDiscourseやインポーター スクリプトのせいではありません。しかし、トピックの返信(Drupalの専門用語では「コメント」)が編集されると、created タイムスタンプが時々変更されることが判明しました。私の知る限りでは、changed タイムスタンプが変更されるべきです。しかし、Drupalのこのバグにもかかわらず、コメントのスレッドは正しく維持されています。しかし、DiscourseのDrupalインポーター スクリプトの動作方法では、返信はcreated タイムスタンプでソートされるようです(drupal.rb スクリプトに ORDER 句は見当たりませんが)。DrupalデータベースでのphpMyAdminでのテストから、元のDrupalコメントID cid(これは連続しており、決して変更されません)を介して正しいスレッド順序を維持するには、単に ORDER BY c.cid ASC が必要であることがわかりました。しかし、Discourseインポーターが連続した返信に順序が狂った日付を許可するかどうか、また、Discourseインポーターが独自の投稿日時によるソートを行うかどうかはわかりません。drupal.rb インポーターの元の作成者(および明らかに他の誰か)の意見を聞きたいのですが、これは機能しますか?また、意図しない結果はありますか?

(でも、よくわからないのですが、Drupalのデータベースは私には意味不明なので、投稿の作成日時を編集されたものではなく、元の投稿から取得するようにクエリを調整できると思います。)

(元の投稿/時間を格納するテーブルと、編集を格納する別のテーブルがあると思います。)

cidで並べ替えても何も害はないと思います。)

「いいね!」 1

まったく意味がありません。問題はこうです。強調表示された 2 行は、スレッドの 2 番目と 3 番目の返信であるはずですが、Discourse ではタイムスタンプがそこにあるため、500 番目の位置よりも後のどこかにあります。

そしてもちろん、Drupal は createdchanged を同じものに設定しました… そしてそれは時々しか発生せず、古い投稿を編集しても自分で再現できません。しかし、トピックの OP が投稿し、その後すぐに後で追加情報を提供するために「予約済み」という本文を含む 1 つまたは 2 つのフォローアップ コメントを投稿し、それを数年後に行った、複数の長期スレッドで同じ問題が発生しています。

それは理にかなっていますが、ここに、それが使用する 2 つのテーブルにまたがる、同じ問題のある編集されたコメントがあります。


「いいね!」 1

OK、これは機能するようです。見つかった 2 つの順序が混在したスレッドが修正され、他のものには影響がないようです。

  def import_replies

    batches(BATCH_SIZE) do |offset|
      results = mysql_query(<<-SQL
        SELECT c.cid, c.pid, c.nid, c.uid, c.created,
               f.comment_body_value body,
               f.comment_body_format format
          FROM comment c,
               field_data_comment_body f,
               node n
         WHERE c.cid = f.entity_id
           AND n.nid = c.nid
           AND c.status = 1
           AND n.type IN ('poll', 'forum')
           AND n.status = 1
           AND c.created > UNIX_TIMESTAMP(STR_TO_DATE('#{IMPORT_AFTER}', '%Y-%m-%d'))
         ORDER BY c.cid ASC  #<--- Fixed
         LIMIT #{BATCH_SIZE}
        OFFSET #{offset}
      SQL
      ).to_a
「いいね!」 1

うーん、これは自分に返ってきたようです。postprocess_posts関数は古い内部リンクを新しいDiscourse URLに置き換えるため、Wayback Machineの古いDrupal投票用に作成したhttps://web.archive.org/web/20230101093741/https://MyOldForum.com/node/98765リンクのコードに例外を設けていました。しかし、何かがうまくいかなかったようで、本番の移行済みサイトでリンクがhttps://web.archive.org/web/20230101093741/https://MyOldForum.com/t/-/12345のようになったことに気づきました。

移行コンテナのコンテキストに artık なくなったので、DiscourseトピックDBテーブルに元のDrupalノードのnidを持つカスタムフィールドはまだ利用可能でしょうか?もしそうであれば、Railsコンソールで、View this poll on the Wayback Machineを含む最初の投稿を持つすべてのトピックに対して文字列置換を実行し、

https://web.archive.org/web/20230101093741/https://MyOldForum.com/t/-/[01234567890]*

https://web.archive.org/web/20230101093741/http://MyOldForum.com/node/$original_nid

に置き換えることが可能だと思われます。

元の投票インポート関数は次のとおりです。

    def import_poll_topics
    puts '', "importing poll topics"

    polls = mysql_query(<<-SQL
      SELECT n.nid nid, n.title title, n.uid uid, n.created created, n.sticky sticky, taxonomy_index.tid tid, node_counter.totalcount views
        FROM node n
        LEFT JOIN taxonomy_index ON n.nid = taxonomy_index.nid
        LEFT JOIN node_counter ON n.nid = node_counter.nid
       WHERE n.type = 'poll'
         AND n.status = 1
    SQL
    ).to_a

    create_posts(polls) do |topic|
      {
        id: "nid:#{topic['nid']}",
        user_id: user_id_from_imported_user_id(topic['uid']) || -1,
        category: category_id_from_imported_category_id(topic['tid']),
        # TEMPmyoldforum.comを使用してください。そうしないと、postprocess_posts()がWayback Machineの/node/YYYリンクを変換しようとします。
        raw: "### View this poll on the Wayback Machine:\n**https://web.archive.org/web/20230101093741/http://TEMPmyoldforum.com/node/#{topic['nid']}**",
        created_at: Time.zone.at(topic['created']),
        pinned_at: topic['sticky'].to_i == 1 ? Time.zone.at(topic['created']) : nil,
        title: topic['title'].try(:strip),
        views: topic['views'],
        custom_fields: { import_id: "nid:#{topic['nid']}" }
      }
    end
  end

はい。

t=Topic.find(1234)
t.custom_fields
t.custom_fields['import_id']
「いいね!」 1