親メッセージが存在しません

mbxs のインポート時に、親メッセージが存在しないというエラーが発生しています。しかし、index.db には親メッセージが確かに存在しているようです。

エラー内容は以下の通りです:

Parent message 9205270657.AB03850@ben.dciem.dnd.ca doesn’t exist. Skipping 9206031720.AA22567@ben.dciem.dnd.ca: A CALL FOR HELP

データベースのエントリーは以下の通りです:

Annotation 2020-02-16 155700

この失敗の原因について、何かご提案はありますか?

ソート順が正しくないのは、メールを件名でグループ化しているからかもしれません。調査する価値があるでしょう。メッセージは Subject と mbox ファイル内のメールの順序でしかソートされません。

本当にメールを件名でグループ化する必要があるのでしょうか?スクリーンショットを見る限り、メールには正しい Message-ID の他に In-Reply-To および References ヘッダーも含まれているようです。

ありがとうございます。email_order テーブルを確認すると、順序は正しいように見えます。

msg_id rowid
9205270657.AB03850@ben.dciem.dnd.ca 874
9206031720.AA22567@ben.dciem.dnd.ca 875

親メッセージのインポートに失敗している他の要因があるのでしょうか?

最初のインポートを行った際は、グループ化が全く行われていないように見えました。問題の根源は、返信が発信者ではなくメーリングリスト宛てになっている点にあると思います。また、アーカイブが28年もの間、異なるバージョンの Eudora を使いながら手作業で非常に不規則にまとめられたため、一部のメッセージにはこれらのフィールドが全く含まれていません。

親メッセージのインポートに失敗したのかもしれません。エラーはありましたか?なぜメッセージが見つからないのか判断するのは難しいです。申し訳ありませんが、インポートスクリプトの Ruby コードを修正して、ご自身でデバッグしていただく必要がありそうです。

いいえ、エラーがあったとは考えません。

わかりました。Ruby やインポートスクリプトには慣れていませんが、やってみることはできるかもしれません。
どのスクリプトを確認すればよいか、またその場所はどこか教えていただけますか?「デバッグ」とは、print 文を追加することを意味するのでしょうか、それともより高度な機能があるのでしょうか?

https://github.com/discourse/discourse/tree/master/script/import_scripts/mbox

さて、map_first_post にいくつかのデバッグ用 print を追加しました。

def map_first_post(row)
  puts "Mapping parent #{row['msg_id']} #{row['subject'][0..40]}"
  mapped = map_post(row)
  mapped[:category] = category_id_from_imported_category_id(row['category'])
  mapped[:title] = row['subject'].strip[0...255]
  mapped
  puts "Mapped message #{row['msg_id']} #{row['subject'][0..40]}"
end  

def map_reply(row)
  parent = @lookup.topic_lookup_from_imported_post_id(row['in_reply_to'])
  if parent.blank?
    puts "Parent message #{row['in_reply_to']} doesn't exist. Skipping #{row['msg_id']}: #{row['subject'][0..40]}"
    return nil
  end

  mapped = map_post(row)
  mapped[:topic_id] = parent[:topic_id]
  mapped
end

これらの出力は正常で、親メッセージがマッピング(インポート?)されていることを示しています。

873 / 65936 ( 1.3%) [3895 items/min]
Mapping parent 9205270657.AB03850@ben.dciem.dnd.ca A CALL FOR HELP
Mapped message 9205270657.AB03850@ben.dciem.dnd.ca A CALL FOR HELP
874 / 65936 ( 1.3%) [3900 items/min]
Parent message 9205270657.AB03850@ben.dciem.dnd.ca doesn’t exist. Skipping 9206031720.AA22567@ben.dciem.dnd.ca: A CALL FOR HELP

したがって、なぜ map_reply で親が空白になるのか分かりません。唯一気づくのは、番号(873/874)が上記の rowid より 1 つ小さいことです。

しかし、@lookup.topic_lookup_from_imported_post_id が何をしているのか分からないため、これ以上進めることは難しいでしょう。vi で編集してインポートを再実行するのは非常に手間がかかり、1 サイクルあたり約 30 分かかります。

それは同じディレクトリにある base.rb にあります。関数名が示す通り、トピックのカスタムフィールド(あるいは投稿のカスタムフィールドかもしれません)から import_id(この場合はメッセージ ID だと推測されます)を検索して topic_id を特定しています。

1 週間かかるものよりはマシですね。:wink:(インポートスクリプトがデバッグ対象のデータのみをインポートするように設定できる場合がありますが、その方法は読者への課題として残しておきます。)

データベースを確認して、親メッセージがインポートされているか、また import_id というトピック/投稿のカスタムフィールドを持っているか確認してみてください。

どこを探しているのでしょうか?topic_id は件名のことですか?

「データベース」というのは index.db のことを指していますか?「インポートされた」というのは index.db のメールテーブルに入力されたことを意味しますか?はい、そこにはあります。しかし、「import_id」という名前の列はありません。

データベースとは Discourse のデータベースを指します。インポート ID は topic_custom_field テーブルと post_custom_field テーブルにあります。

ああ!

データエクスプローラープラグインをインポートして、Discourseデータベースを確認しました。親メッセージの import_id が topic_custom_field テーブルと post_custom_field テーブルに存在していることがわかりました。また、そのメッセージ自体も存在していました。

しかし、そのメッセージは削除されていました。つまり、「親メッセージが存在しません」というエラーが発生したのは、インポート処理が index.db ではなく Discourseデータベースを検索していたためだと考えられます。もし「投稿が削除されています」といったエラーメッセージが表示されていれば、より良かったのですが。

とにかく、これは初期テスト中に最初の(小規模な)インポート済み投稿のバッチを削除してしまったことが原因だったようです。その時点以前に復元したつもりでしたが、どうやら実際には復元できていなかったようです。

幸いなことに、これはテストサーバーでのみ発生した問題であり、本番サーバーでのインポートでは同様の問題が発生しないはずです。

ヒントをいただき、ありがとうございました。

なぜ?誰が?

これはインポート時に発生するものではありません。

その通りですね。投稿を削除しても、実際には削除されるのではなく、削除済みとしてマークされるだけです。