Vbulletin 批量导入程序:关系 "topics" 的列 "pinned_globally" 中的空值违反了非空约束

我正在尝试使用 vbulletin 批量导入器进行导入。我设法让它大部分完成了。它创建了用户和帖子,但主题没有被创建。

传递给 create_topics(topics) 的内容看起来是正确的。base.rb:create_recordsprocessed 中的内容看起来是正确的(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 added this:
      }
      t[:pinned_at] = created_at if row[8] == 1

      t
    end

这很奇怪,因为该列有一个默认值?在您执行 \\d topics 时,您的数据库中是否有默认值?

pinned_globally | boolean | | not null | false

嗯。我想这解释了为什么它不在代码中。

但这并没有解开谜团。

pinned_globally    | boolean   |     | not null | false

编辑:

随机 AI 说:

也许这是一个“批量插入工具”?

我找不到任何可靠的来源说明上述引述的内容,但它确实有道理,因为这里的重点是速度快,所以跳过默认值似乎是它会做的事情,而且它确实解释了正在发生的事情,并且,我希望,我仍在等待看是否有效的解决方案。

这是实际文档!PostgreSQL: Documentation: 18: COPY

如果指定了列列表,COPY TO 只会将指定列中的数据复制到文件中。对于 COPY FROM,文件中的每个字段将按顺序插入到指定的列中。COPY FROM 列列表中未指定的表列将接收其默认值。

所以,如果我没看错的话,如果一个字段在字段列表中,那么 postgres 会盲目地复制你给它的东西,并且会插入空/null 而不是期望的默认值。

速度越来越慢。有没有理由不像常规导入器那样使用 LIMIT 1000?一次处理 885K 个主题似乎有点多?

{“translation”: "我检查了我最后一次批量导入的脚本,确实有明确的 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
      }

奇怪的是,它没有像 closedhas_summary 等其他类似的 not null, default false 列那样设置这个参数。

[引用者=“pfaffman, 第3帖, 主题=366162”]
导入速度越来越慢。是否有理由不用 LIMIT 1000,就像常规导入器那样?似乎一次处理大约 88 万个主题可能太多了?
[/引用]
我上一次使用批量导入器导入的速度是大约 2 小时内完成了 300 万多个主题。可能是你的内存泄漏?或者可能是你用来读取源数据的 MySQL 代码(或者你用的其他任何工具)某个地方很慢?"}

好消息!所有主题都已创建!坏消息!没有帖子与它们相关联,但希望这是因为帖子是在主题创建之前创建的。

这很奇怪。我确信我有一个解释。 :person_shrugging:

700 万个帖子只花了几个小时,但不到 100 万个主题却花了大约 4 个小时。

这是一台旧机器(他们显然是专门为此工作而购买的?),并且 mysql 是远程的。查看 htop,系统级别没有明显的内存泄漏。我已经删除了所有数据,并正在重建容器,看看这次是否能正常工作。

非常感谢你的帮助。

1 个赞

好吧,现在 user_email 导入失败,错误信息如下:

CONTEXT:  COPY user_emails, 第1行:"1  \N      @gmail.com     true    2004-03-08 14:12:00 UTC 2004-03-08 14:12:00 UTC"

又花了几个小时,我终于明白了原因——process_topic 函数处理了所有这些默认值。

我猜应该有一个

topic[:pinned_globally] ||= false

或者也许

topic[:pinned_globally] ||= topic[:pinned_at].nil?
1 个赞