将phpBB3论坛迁移到Discourse

是否可以将 phpBB论坛导入现有的 Discourse 论坛,即合并它们?我假设这是基于关于映射类别的设置。

有什么需要注意的问题吗?

如果用户的电子邮件地址相同,是否会合并用户?

1 个赞

是的。如果你不在设置文件中进行自己的类别映射,在导入过程中会根据需要创建新的类别。如果 Discourse 中已有的类别名称与 phpbb 的类别名称匹配,则类别将合并。

哦,是的。这是一个详细介绍我遇到的情况的帖子。我有一些技巧,还有一个包含我对导入器合并更新的仓库。

我不记得确切的条件了,但是的,用户在导入过程中会自动合并。

2 个赞

我想知道是否可以将 phpbb3 论坛合并到 Discourse 中,同时将所有导入的主题保留为只读。搜索了该主题,但没有看到提及这一点。谢谢。

您可以修改导入脚本以存档所有创建的主题,或者在脚本运行后批量执行此操作可能更容易。有关示例,请参阅 https://meta.discourse.org/t/administrative-bulk-operations/118349。

2 个赞

你好,

我在启动导入器时似乎遇到问题。似乎发生在用户导入期间或之后不久。我已附上堆栈跟踪和一段 20 秒的输出视频。

请告知。

0x00007fe87a88bb10 /var/www/discourse/script/import_scripts/phpbb3/importers/user_importer.rb:87}
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/activerecord-7.0.7/lib/active_record/validations.rb:80:in `raise_validation_error': Validation failed: Name can't be blank (ActiveRecord::RecordInvalid)
        from /var/www/discourse/vendor/bundle/ruby/3.2.0/gems/activerecord-7.0.7/lib/active_record/validations.rb:53:in `save!'
        from /var/www/discourse/vendor/bundle/ruby/3.2.0/gems/activerecord-7.0.7/lib/active_record/transactions.rb:302:in `block in save!'
        from /var/www/discourse/vendor/bundle/ruby/3.2.0/gems/activerecord-7.0.7/lib/active_record/transactions.rb:354:in `block in with_transaction_returning_status'
        from /var/www/discourse/vendor/bundle/ruby/3.2.0/gems/activerecord-7.0.7/lib/active_record/connection_adapters/abstract/database_statements.rb:314:in `transaction'
        from /var/www/discourse/vendor/bundle/ruby/3.2.0/gems/activerecord-7.0.7/lib/active_record/transactions.rb:350:in `with_transaction_returning_status'
        from /var/www/discourse/vendor/bundle/ruby/3.2.0/gems/activerecord-7.0.7/lib/active_record/transactions.rb:302:in `save!'
        from /var/www/discourse/vendor/bundle/ruby/3.2.0/gems/activerecord-7.0.7/lib/active_record/suppressor.rb:54:in `save!'
        from /var/www/discourse/script/import_scripts/base.rb:361:in `block in create_user'
        from /var/www/discourse/vendor/bundle/ruby/3.2.0/gems/activerecord-7.0.7/lib/active_record/connection_adapters/abstract/transaction.rb:319:in `block in within_new_transaction'
        from /var/www/discourse/vendor/bundle/ruby/3.2.0/gems/activesupport-7.0.7/lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `handle_interrupt'
        from /var/www/discourse/vendor/bundle/ruby/3.2.0/gems/activesupport-7.0.7/lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `block in synchronize'
        from /var/www/discourse/vendor/bundle/ruby/3.2.0/gems/activesupport-7.0.7/lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `handle_interrupt'
        from /var/www/discourse/vendor/bundle/ruby/3.2.0/gems/activesupport-7.0.7/lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `synchronize'
        from /var/www/discourse/vendor/bundle/ruby/3.2.0/gems/activerecord-7.0.7/lib/active_record/connection_adapters/abstract/transaction.rb:317:in `within_new_transaction'
        from /var/www/discourse/vendor/bundle/ruby/3.2.0/gems/activerecord-7.0.7/lib/active_record/connection_adapters/abstract/database_statements.rb:316:in `transaction'
        from /var/www/discourse/vendor/bundle/ruby/3.2.0/gems/activerecord-7.0.7/lib/active_record/transactions.rb:209:in `transaction'
        from /var/www/discourse/script/import_scripts/base.rb:360:in `create_user'
        from /var/www/discourse/script/import_scripts/base.rb:278:in `block in create_users'
        from /var/www/discourse/vendor/bundle/ruby/3.2.0/gems/rack-mini-profiler-3.1.1/lib/patches/db/mysql2/alias_method.rb:8:in `each'
        from /var/www/discourse/vendor/bundle/ruby/3.2.0/gems/rack-mini-profiler-3.1.1/lib/patches/db/mysql2/alias_method.rb:8:in `each'
        from /var/www/discourse/script/import_scripts/base.rb:266:in `create_users'
        from /var/www/discourse/script/import_scripts/phpbb3/importer.rb:106:in `block in import_anonymous_users'
        from /var/www/discourse/script/import_scripts/base.rb:948:in `block in batches'
        from /var/www/discourse/script/import_scripts/base.rb:947:in `loop'
        from /var/www/discourse/script/import_scripts/base.rb:947:in `batches'
        from /var/www/discourse/script/import_scripts/phpbb3/importer.rb:293:in `batches'
        from /var/www/discourse/script/import_scripts/phpbb3/importer.rb:102:in `import_anonymous_users'
        from /var/www/discourse/script/import_scripts/phpbb3/importer.rb:33:in `execute'
        from /var/www/discourse/script/import_scripts/base.rb:47:in `perform'
        from /var/www/discourse/script/import_scripts/phpbb3/importer.rb:22:in `perform'
        from script/import_scripts/phpbb3.rb:35:in `<module:PhpBB3>'
        from script/import_scripts/phpbb3.rb:16:in `<module:ImportScripts>'
        from script/import_scripts/phpbb3.rb:15:in `<main>'

编辑:
看起来这与匿名用户有关,我想我会查看我的数据库

 def map_anonymous_user(row)
      username = row[:post_username]

      {
        id: @settings.prefix(username),
        email: "anonymous_#{SecureRandom.hex}@no-email.invalid",
        username: username,
        name: @settings.username_as_name ? username : "",
        created_at: Time.zone.at(row[:first_post_time]),
        active: true,
        trust_level: TrustLevel[0],
        approved: true,
        approved_by_id: Discourse.system_user.id,
        approved_at: Time.now,
        post_create_action:
          proc do |user|
            row[:user_inactive_reason] = Constants::INACTIVE_MANUAL
            row[:ban_reason] = "Anonymous user from phpBB3" # TODO i18n
            suspend_user(user, row, true)
          end,
      }
    end

编辑
我通过更改 map_anonymous_user 方法中的这行代码,成功地让它绕过了错误。原来默认是将用户名设置为空字符串,所以我只是在其中添加了一个词。

更改此

name: @settings.username_as_name ? username : "",

至此

name: @settings.username_as_name ? username : "Anonymous ",
3 个赞

在运行增量导入之前,我可以删除旧帖子吗?我已经在本地的开发安装中成功运行了导入,并将其恢复到运行 Docker 安装的服务器上,我的计划是在那里为新帖子运行导入。但是,即使忽略已经导入的帖子,在服务器上运行导入也需要数小时。我的论坛很大(130 万个帖子),并且我的服务器磁盘很慢,因此仅加载 .sql 文件就需要数小时。

在本地执行类似 DELETE FROM phpbb_posts WHERE post_id < 2926807 的操作,然后将其转储并上传到服务器并像往常一样运行导入,会引起问题吗?

我为一些脚本添加了 IMPORT_AFTER 设置,使其仅提取某个日期之后的数据。因此,我会修改用于提取帖子的 SQL,以仅获取上次数据转储前一天之后的数据。

但是,如果你的磁盘速度非常慢,那么托管 Discourse 可能会遇到麻烦。在你拥有的数据量下,性能是否可以接受?

1 个赞

是的,正常使用时我会使用一个更快的磁盘,但它不足以同时托管多个数据库副本,因此我在 import.yml volumes 部分将 /shared/import 路由到一个更大、更慢的磁盘。这个技巧在恢复初始备份时效果很好,恢复失败(即使有 18G 空间和 6G 数据库,但空间不足)后,我将 /shared/tmp 重新路由到慢速磁盘(我认为你之前提到过恢复运行时会创建数据库的 3 个副本)。但那个阶段停机时间不是问题。

所以日常使用中,大小和速度都不是问题,我的论坛很安静,只是有点老了。

我会看看修改脚本中的 SQL。谢谢!

2 个赞

在 settings.yml 中,连接到 mysql 的内容是这样的:


我可以在哪里放置数据库名称?

数据库名称应放在 schema 参数中。该参数的名称有点令人困惑,是的。您可以在代码中的此处看到,它作为数据库名称传递。

2 个赞

https://www.loom.com/share/1f66315779af4cf7b286c8541d4f3f09

您好!我录制了一个简短的视频,谈论我们遇到的导入问题。我们正在迁移大约 650,000 篇帖子。

非常感谢!

https://www.loom.com/share/1f66315779af4cf7b286c8541d4f3f09?sid=11a46d3c-8510-43a1-82e9-1a3524cbb365

您好。有没有办法逐行执行导入?我们的脚本在完成时遇到了问题。有些内容可以正常工作,例如用户和头像,但有些则不行。我已经重新安装了我的服务器大约 4 次,因为我在某处读到导入失败后需要进行全新安装。

其他详细信息在我发布的视频中。感谢您的任何帮助。

您好。我花了大约 18 个小时进行迁移,但迁移工作仍未成功。您能否观看我的视频并就是否有任何技巧或窍门提供建议,或者是否有配置遗漏的地方?我们只需要帖子、主题、私人消息、类别。头像和用户正在工作。服务器是干净的 UBUNTU 22.04。

一个更简单的解决方案是在创建站点后进行备份,这样您就可以恢复该站点。另一种获取干净数据库的方法是执行 rake db:drop db:create db:migrate,但这需要做一些事情才能使其成为可能。如果您无法从错误消息中猜出这些内容,那么备份/恢复解决方案就是可行的方法,而且可能更快。

您可以在其中添加一些调试 puts 语句,尽管 phpbb3 脚本的结构对于不熟悉 Ruby 的人来说有点令人困惑。

另外,您可以多次运行脚本,它会跳过已经完成的部分,因此在更改需要重新开始的内容之前,您实际上不需要擦除数据库(也就是说,它会处理已导入的数据,但会执行不同的操作)。

这超出了我免费能做的范围。如果您有预算,可以直接联系我或发布到 #marketplace。

导入脚本似乎不起作用。问题出在视频中。如果来自 discourse migrations 的人能对此进行调查,我们将不胜感激。

如果支持是收费的,你们能列出迁移的成本吗?我的理解是,这是我们提出关于如何让脚本正常工作的问题的地方。我没意见收费,我只是以为这是一个开源项目,而这里是我们提出问题的地方。

我的意思是,我在这里是志愿服务的,我不想免费观看视频,这在很大程度上是因为我对视频的非理性厌恶。但这里不止我一个人。很多人喜欢看视频。

所以每次运行它都会创建之前运行中创建的用户的副本?我无法想象怎么会这样。你确定吗?它本不应该这样工作。

它看起来会再次导入内容,但速度会快得多,因为它实际上什么也没做,因为已经导入的内容已经设置了一个 import_id 自定义字段,可以防止它再次导入。如果每次运行都复制数据,那说明有什么非常奇怪的问题。

是的。有时人们需要或想要的帮助比免费获得的要多。

2 个赞

好的。您能否公布一下迁移费用?我明白脚本似乎无法正常工作,需要付费支持。我对此完全没意见。

1 个赞

迁移相当复杂。每一次迁移都有不同的挑战,因为每个论坛的数据都是独一无二的。调试迁移问题可能需要数小时,并且需要深入查看日志、数据库、代码等。仅凭查看这些帖子很难做到,抱歉我无法提供更多帮助!这是我们的迁移常见问题解答:Migrating to Discourse | Discourse - Civilized Discussion

谢谢链接。我想我已经解决了问题,导入脚本现在正在运行。我目前大约有 100000/666357 条帖子。ChatGPT 在识别一些基于权限的错误等方面很有帮助。

2 个赞