pfaffman
(Jay Pfaffman)
1
vBulletin の一括インポーターでインポートを試みています。ほとんど完了しましたが、ユーザーと投稿は作成されたものの、トピックが作成されていません。
create_topics(topics) に渡されている内容は正しく見えます。base.rb:create_records の processed 内の内容も正しく見えます(skipped は設定されていません)。しかし、トピックが作成されていません。
以下がエラーです。
ERROR: column "pinned_globally" of relation "topics" contains null value violates not-null constraint
しかし、トピックがグローバルにピン留めされていない場合、どのような値になるべきでしょうか? base.rb の TOPIC_COLUMNS でそのフィールドをコメントアウトしようとしています。
編集:これが解決策になるかもしれませんが、しばらくはわかりません。
create_topics(topics) do |row|
created_at = Time.zone.at(row[5])
t = {
imported_id: row[0],
title: normalize_text(row[1]),
category_id: category_id_from_imported_id(row[2]),
user_id: user_id_from_imported_id(row[3]),
closed: row[4] == 0,
created_at: created_at,
views: row[6] || 0,
visible: row[7] == 1,
pinned_globally: row[8] == 1 # ============== JP が追加
}
t[:pinned_at] = created_at if row[8] == 1
t
end
RGJ
(Richard - Communiteq)
2
それは奇妙ですね。その列にはデフォルト値があるはずですが? \\d topics を実行したときに、データベースにデフォルト値はありますか?
pinned_globally | boolean | | not null | false
pfaffman
(Jay Pfaffman)
3
なるほど。それがコードにない理由だと思います。
しかし、謎は解けません。
pinned_globally | boolean | | not null | false
編集:
ランダムAIによると:
これは「一括挿入ツール」かもしれません。
上記の引用が述べていることを信頼できる情報源で見つけることができませんでしたが、それは理にかなっています。この目的は速度を出すことなので、デフォルトをスキップすることは行うべきことのように思えます。そして、それは何が起こっているのかを説明しており、うまくいったことを願っている解決策でもあります。
ここに実際のドキュメントがあります! PostgreSQL: Documentation: 18: COPY
列リストが指定されている場合、COPY TO は指定された列のデータのみをファイルにコピーします。COPY FROM の場合、ファイル内の各フィールドは、指定された順序で指定された列に挿入されます。COPY FROM 列リストに指定されていないテーブル列には、デフォルト値が設定されます。
したがって、私が正しく読んでいる場合、フィールドがフィールドリストにある場合、postgres は提供されたものを盲目的にコピーし、目的のデフォルトの代わりに空白/nullが挿入されます。
どんどん遅くなっています。通常のインポーターが行っているように LIMIT 1000 を使用しない理由がありますか? 一度に 885K トピックを処理するのは多すぎるかもしれません。
RGJ
(Richard - Communiteq)
4
前回のバルクインポートで使用したスクリプトを確認したところ、確かに明示的な pinned_globally: false が含まれており、それが不可欠であることがわかりました。これは、コード内で明示的にハードコーディングされた唯一の列値です。
create_topics(topics) do |row|
t = {
imported_id: row[0],
title: my_normalize_text(row[1]),
category_id: category_id_from_imported_id(row[2]),
user_id: user_id_from_imported_id(row[3]),
created_at: Time.zone.at(row[4]),
pinned_globally: false
}
closed や has_summary のような、他の類似の not null, default false 列にはこのような設定がないため、奇妙です。
前回のインポートでは、バルクインポーターを使用して約2時間で300万以上のトピックを処理しました。メモリリークがあるのではないでしょうか?それとも、MySQLコード(またはソースデータを読み取るために使用しているもの)のどこかが遅いのでしょうか?
pfaffman
(Jay Pfaffman)
5
朗報です!すべてのトピックが作成されました!悪い知らせです!投稿のどれもトピックに接続されていませんが、うまくいけば、それは投稿がトピックより先に作成されたためでしょう。
それは奇妙ですね。私は説明を確信していました。 
700万件の投稿はわずか数時間しかかかりませんでしたが、100万件未満のトピックには約4時間かかりました。
それは古いマシン(明らかにその仕事のために購入したばかり?)であり、mysql はリモートです。 htop を見ても、システムレベルで明らかなメモリリークはありません。データをすべて消去し、コンテナを再構築して、今回うまくいくかどうかを確認しています。
ご協力いただき、誠にありがとうございます。
「いいね!」 1
pfaffman
(Jay Pfaffman)
6
さて、user_email のインポートが次のエラーで失敗しています。
CONTEXT: COPY user_emails, line 1: "1 \N @gmail.com true 2004-03-08 14:12:00 UTC 2004-03-08 14:12:00 UTC"
pfaffman
(Jay Pfaffman)
7
さらに数時間かかりましたが、理由は次のとおりです。process_topic 関数がこれらのデフォルト値すべてを処理しています。
おそらく、次のようなものが必要だと思います。
topic[:pinned_globally] ||= false
または、おそらく
topic[:pinned_globally] ||= topic[:pinned_at].nil?
「いいね!」 1