将 bbPress WordPress 插件论坛迁移到 Discourse

我最近成功使用 Discourse 内置的迁移脚本完成了 bbPress 数据库迁移。现在,我将以分步教程的形式分享这一过程。

注意:本教程适用于 bbPress 插件,而非 bbPress 的旧版独立版本。

可以导入哪些数据?

  • 用户(包括匿名用户)
  • 分类
  • 主题
  • 帖子
  • 私信(通过 BuddyPress)
  • 附件
  • 固定链接

在开始迁移之前,请在您的机器上(或在虚拟机内)设置开发环境,并在那里运行导入操作,而不是在 Docker 容器内运行。当我尝试在 Docker 容器内运行时,遇到了 peer authentication failed(对等认证失败)问题。因此,我强烈建议您使用开发机器。请参阅 macOSUbuntu / Debian 的开发安装指南。

Discourse 需要 Ruby 3.4 或更高版本。您可以使用以下命令检查您的 Ruby 版本:

ruby -v

接下来,我们需要安装 libmysqlclient-dev 依赖项,以便能够使用 mysql2 gem。

sudo apt-get install libmysqlclient-dev

安装成功后,进入您的 Discourse 开发安装路径(通常为 ~/discourse)。

cd ~/discourse

配置数据库连接

bbPress 导入脚本会从环境变量中读取所有数据库连接设置。您无需编辑脚本文件。支持以下环境变量:

变量 默认值 描述
BBPRESS_HOST localhost MySQL 数据库主机
BBPRESS_USER root MySQL 用户名
BBPRESS_PW (空) MySQL 密码
BBPRESS_DB bbpress MySQL 数据库名称
BBPRESS_PREFIX wp_ WordPress 表前缀
BBPRESS_ATTACHMENTS_DIR /path/to/attachments bbPress 附件目录路径

如果您正在迁移本地主机(localhost)上的数据库,通常只需设置数据库名称:

IMPORT=1 bundle && IMPORT=1 BBPRESS_DB="my_bbpress" bundle exec ruby script/import_scripts/bbpress.rb

如果您正在迁移外部服务器上的数据库,则还需要设置主机、用户名和密码:

IMPORT=1 bundle && IMPORT=1 BBPRESS_HOST="REMOTE_HOST_NAME" BBPRESS_USER="DB_USERNAME" BBPRESS_PW="MY_SECURE_PASSWORD" BBPRESS_DB="DB_NAME" bundle exec ruby script/import_scripts/bbpress.rb

恭喜! 您的数据库已成功从 bbPress 迁移到 Discourse :clap: :wave: :boom:

现在,请从管理页面 /admin/backups 备份数据,并将其导入到您的线上 Discourse 网站中。


将 bbPress 论坛迁移到 Discourse 后,如果您仍计划将 WordPress 网站作为主站点使用,并希望将其与 Discourse 连接,请安装 Discourse 官方 WordPress 插件

15 个赞

Just wanted to thank you for providing this step-by-step guide. We migrated our site from bbpress to Discourse with minimal headache thanks to you. Since we’re running multisite wordpress there were a few tweaks to make to the importer, but other than that it went very smoothly. Thanks!

3 个赞

If you can share your tweaks then it will be helpful to other multisite owners.

1 个赞

Admittedly I didn’t take very good notes, and have since killed the VM it
was on (sorry!) but the basic gist is that if your bbpress install is not
on the primary site of the Multisite setup you’ll need to a) set the
environmental variable for BBPRESS_PREFIX to include your site’s ID number
(e.g. wp_6_ ) and then edit the migration script to use wp_users rather
than #{BBPRESS_PREFIX} for the Users sql. This is because on Multisite
installations the wp_users table is shared across sites and then each site
has its own tables for posts, postmeta, etc.

5 个赞

thanks for the details :thumbsup:

I recently posted on how to import bbpress into discourse

2 个赞

Great job on the tutorial! But it’s confusing to have two different guides on this. Do they serve different purposes? Otherwise we should figure out how to merge them.

That guide is about how to import bbpress inside of a development environment, mine is how to import bbpress using the docker container. It’s just 2 different ways to go. I’d recommend importing via docker container since it doesn’t ask for the additional step of setting up a development environment, which can be cumbersome.

Hello I am stuck trying to import successfully after all users are done importing.

As soon it begins to import anonymous users it cancels with an error of “Invalid Email… and Validation failed: Username can’t be blank (ActiveRecord::RecordInvalid)”.

I added the error below, does anyone encountered this before or have any ideas on what I should do?

Thanks,

importing anonymous users...
Invalid email '' for ''. Using '6be92499a6f885cb271d94bffd5e667b@email.invalid'
Error on record: {:id=>"", :email=>"", :name=>"", :website=>nil}
Traceback (most recent call last):
	23: from script/import_scripts/bbpress.rb:512:in `<main>'
	22: from /home/lutechi/discourse/script/import_scripts/base.rb:49:in `perform'
	21: from script/import_scripts/bbpress.rb:31:in `execute'
	20: from script/import_scripts/bbpress.rb:153:in `import_anonymous_users'
	19: from /home/lutechi/discourse/script/import_scripts/base.rb:249:in `create_users'
	18: from /home/lutechi/discourse/script/import_scripts/base.rb:249:in `each'
	17: from /home/lutechi/discourse/script/import_scripts/base.rb:261:in `block in create_users'
	16: from /home/lutechi/discourse/script/import_scripts/base.rb:337:in `create_user'
	15: from /home/lutechi/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/transactions.rb:212:in `transaction'
	14: from /home/lutechi/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/connection_adapters/abstract/database_statements.rb:267:in `transaction'
	13: from /home/lutechi/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/connection_adapters/abstract/transaction.rb:236:in `within_new_transaction'
	12: from /home/lutechi/.rbenv/versions/2.6.2/lib/ruby/2.6.0/monitor.rb:230:in `mon_synchronize'
	11: from /home/lutechi/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/connection_adapters/abstract/transaction.rb:239:in `block in within_new_transaction'
	10: from /home/lutechi/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/connection_adapters/abstract/database_statements.rb:267:in `block in transaction'
	 9: from /home/lutechi/discourse/script/import_scripts/base.rb:338:in `block in create_user'
	 8: from /home/lutechi/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/suppressor.rb:48:in `save!'
	 7: from /home/lutechi/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/transactions.rb:315:in `save!'
	 6: from /home/lutechi/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/transactions.rb:385:in `with_transaction_returning_status'
	 5: from /home/lutechi/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/transactions.rb:212:in `transaction'
	 4: from /home/lutechi/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/connection_adapters/abstract/database_statements.rb:265:in `transaction'
	 3: from /home/lutechi/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/transactions.rb:387:in `block in with_transaction_returning_status'
	 2: from /home/lutechi/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/transactions.rb:315:in `block in save!'
	 1: from /home/lutechi/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/validations.rb:52:in `save!'
/home/lutechi/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/validations.rb:80:in `raise_validation_error': Validation failed: Username can't be blank (ActiveRecord::RecordInvalid)

感谢这篇有用的教程——对我很有效,不过我遇到了几个小问题:

  1. 安装过程似乎安装了 PostgreSQL 11,而 Discourse 托管版本仅支持 PostgreSQL 10,这让他们有点头疼!

  2. 我导入的用户似乎无法使用他们的 WordPress 凭据登录 Discourse。我用自己的账户尝试过,无论是用用户名还是电子邮件地址,都无法登录。我可以正常登录 WordPress,该用户账户也存在于 Discourse 中,并关联了相应的论坛主题。难道是密码或认证机制发生了变化?

您是否正在使用 WordPress 的单点登录(SSO)?

这需要 迁移密码插件。你安装过它吗?

3 个赞

你好,Michael,

不,这是我找到的关于该插件的首个参考,所以感谢你的提醒——也许我在某个步骤上遗漏了什么!感谢分享,我明天会仔细查看,那时我的眼睛就不会这么累了!

Ruth

3 个赞

你好 :waving_hand:

用户上传的图片也可以迁移吗?
用户上传功能使用的插件是 GD bbPress Attachments

干杯 :beers:

脚本似乎导入了附件。

您需要设置一个名为 BB_PRESS_ATTACHMENTS_DIR 的环境变量,其值为附件的路径。

1 个赞

bbPress 插件的上传文件似乎存储在 WordPress 安装目录的 /uploads 文件夹中。这是通过 GD bbPress Attachments 插件实现的。我不确定应该在 BB_PRESS_ATTACHMENTS_DIR 变量中填入哪种路径。您能稍微帮忙解答一下吗?我应该填入上传文件的完整 URL 路径,例如 http://www.example.com/httpdocs/wp-content/uploads/2018/02/picture.png,还是其他什么?

我发现导入脚本并未成功完成,因为 import_private_messages 步骤失败了。论坛中未启用私信功能。我移除了脚本中的该步骤,但脚本现在因报错 table wp_bb_attachments doesn't exist 而失败,这确实是事实。不过我在数据库中找不到任何与附件相关的表。那么这些附件最初是如何工作的呢?:thinking:

附件必须位于运行导入操作的服务器目录中。

如果您看不到脚本正在查找的附件表,可能是您使用了脚本预期之外的附件处理方式。我猜测这些附件要么位于您尚未找到的其他表中,要么相对文件名直接存储在帖子内容中。

看来您需要另一个函数来导入这些附件。如果您有预算,我可以提供帮助。Redirecting… 提供了有关导入的信息。看来您并不需要全套服务,因此您的费用将低于该网站建议的金额。

由于 Discourse 始终在 Docker 容器中运行,该目录是否应该链接到导入容器中?

正确。如果您正在从容器中运行导入操作,则需要将这些镜像放置在一个容器可以访问的位置,并使用该路径。

1 个赞

最后一个问题。既然您提到了您的导入服务,我查看了网站并进一步挖掘了我的数据库,找到了附件的存储位置。您页面上的一个句子让我有些担心:

例如,某些论坛可以将文件附加到帖子中,而无需在消息正文中提及它们。导入脚本通过替换消息正文中对它们的引用来识别附件;当这种情况发生时,这些未链接的附件将被省略。

我发现我的附件存储在 wp_postsmeta 表中,字段为 _wp_attached_file。然而,包含该附件链接的帖子本身在帖子正文中并未提及这一点。似乎这里唯一的链接是 post_id 和它的 meta_id。这是否意味着这是一个“未链接的附件”,将被省略?