将Phorum论坛迁移到Discourse

如果您有一个旧的 Phorum 论坛并考虑迁移到 Discourse,那么本教程非常适合您。该过程非常直接,我们将使用官方的 Phorum 导入脚本。让我们开始吧。

在高层面上,我们将执行以下操作:

  • 准备本地开发环境。
  • 从生产环境导出数据库。
  • 将生产数据库导入到本地 Discourse 实例。
  • 运行 Phorum 导入脚本。

可迁移的内容

  • 分类
    • 每个论坛和文件夹 => 根分类
  • 主题与帖子
  • 用户(包含以下属性)
    • 封禁状态
    • 用户名
    • 真实姓名 => 姓名
    • 邮箱
    • 管理员状态
    • 添加日期
    • 最后活跃时间

准备本地开发环境

按照以下指南之一安装 Discourse,如果您遇到任何问题,请参考 此指南

安装 MySQL 数据库服务器;

Ubuntu 18.04

$ sudo apt update
$ sudo apt install mysql-server -y

完成 MySQL 安装后,检查其状态:

$ systemctl status mysql.service

如果未运行,请执行以下操作:

$ sudo systemctl start mysql

MacOS

$ brew install mysql@5.7
$ echo 'export PATH="/usr/local/opt/mysql@5.7/bin:$PATH"' >> ~/.bash_profile
$ source ~/.bash_profile

检查服务状态:

$ brew services list

您应该看到类似以下内容:

...
mysql@5.7         started
...

否则,请运行以下命令并再次检查:

$ brew services start mysql@5.7

对于 Windows,您可以按照官方 安装指南 进行操作。

此环境将作为我们的 Discourse 服务器

从生产环境导出数据库:

导出生产数据库(来自 Phorum 生产服务器):

$ mysqldump -u USER_NAME -p DATABASE_NAME > phorum_dump.sql

将数据库转储文件复制到 Discourse 服务器

:bulb: 使用 scprsync 复制数据库。当然,您可以先将其压缩为 gzip 格式。

将生产数据库导入 Discourse 服务器

Discourse 服务器 上,创建一个数据库:

$ mysql -u root

:bulb: 如果您的数据库用户有密码,请使用:mysql -u root -p,然后输入您的密码。

mysql> CREATE DATABASE phorum;

确保数据库已创建:

mysql> SHOW DATABASES;

您应该看到类似以下内容:

+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| phorum             |
| sys                |
+--------------------+
5 rows in set (0.04 sec)

这是一个空数据库。我们的下一步是将生产数据库导入其中。

$ mysql -u root phorum < phorum_dump.sql

在此过程中,让我们获取表前缀。我们稍后会用到它:

$ mysql -u root
mysql> USE phorum;
mysql> SHOW TABLES;

您将看到类似以下内容:

+---------------------------+
| Tables_in_phorum          |
+---------------------------+
| pw_banlists           |
| pw_files              |
| pw_forum_group_xref   |
| pw_forums             |
| pw_groups             |
| pw_messages           |
| pw_messages_edittrack |
| pw_pm_buddies         |
| pw_pm_folders         |
| pw_pm_messages        |
| pw_pm_xref            |
| pw_search             |
| pw_settings           |
| pw_subscribers        |
| pw_user_custom_fields |
| pw_user_group_xref    |
| pw_user_newflags      |
| pw_user_permissions   |
| pw_users              |
+---------------------------+
19 rows in set (0.00 sec)

从上述输出中,您可以看到前缀是 pw_

运行 Phorum 导入脚本

首先,安装导入器的依赖项:

$ cd ~/discourse
$ echo "gem 'mysql2', require: false" >> Gemfile
$ bundle install

现在让我们配置脚本以符合我们的需求。在我们的示例中,这将完成:

PHORUM_DB = "phorum"
TABLE_PREFIX = "pw_"
BATCH_SIZE = 1000

# ...

host: "localhost",
username: "root",
password: "", # 如果您的 MySQL 数据库有密码,请修改此处
database: PHORUM_DB

如果您想创建 URL 重定向,则应取消注释以下内容:

# categories.each do |category|
#   Permalink.create(url: "list.php?#{category['id']}", category_id: category_id_from_imported_category_id(category['id'].to_i))
# end

#...

# results.each do |post|
#   if post['parent_id'] == 0
#     topic = topic_lookup_from_imported_post_id(post['id'].to_i)
#     Permalink.create(url: "read.php?#{post['category_id']},#{post['id']}", topic_id: topic[:topic_id].to_i)
#   end
# end

它将是这样的:

categories.each do |category|
  Permalink.create(url: "list.php?#{category['id']}", category_id: category_id_from_imported_category_id(category['id'].to_i))
end

#...

results.each do |post|
  if post['parent_id'] == 0
    topic = topic_lookup_from_imported_post_id(post['id'].to_i)
    Permalink.create(url: "read.php?#{post['category_id']},#{post['id']}", topic_id: topic[:topic_id].to_i)
  end
end

使用干净的 Discourse 实例运行导入器:

bundle exec rake db:drop db:create db:migrate
bundle exec ruby script/import_scripts/phorum.rb

导入器将连接到 MySQL 服务器,并将我们的 Phorum 数据库迁移到 Discourse 数据库。

导入完成后启动 Discourse 服务器:

$ bundle exec rails server

启动 Sidekiq 以处理迁移的数据:

$ bundle exec sidekiq

:bulb: 您可以在 http://localhost:3000/sidekiq/queues 监控 Sidekiq 的进度。

按照本 教程 设置您的 Discourse 生产服务器。

按照本 教程 对 Discourse 数据库进行备份并将其上传到您的 Discourse 生产服务器。

完成 :tada:

7 个赞

我正准备开始将 Phorum 论坛迁移到 Discourse。我希望保留帖子中附加的文件(主要是图片)。看起来当前的迁移脚本尚不支持此功能。是否有人已经研究过这个问题?

1 个赞

我对“phorum”的迁移脚本进行了一些调整,包括迁移附件/文件/上传。拉取请求在此:

1 个赞

感谢提供的脚本!

不过,我觉得手册相当粗糙且不清楚。我不得不参考例如 Xenforo 迁移指南 来真正理解你在这里的建议。让我添加一些缺失的步骤:

  • 运行 Discourse
  • 从原始 Phorum 创建 mysqldump - 一切都很清楚,一切都很好。
  • 将数据库转储复制到 Discourse 文件夹 docker cp /path/to/backup/phorum_db.sql.gz app:/shared/phorum_db.sql.gz(假设 app 是标准的容器名称)
    这里是缺失的部分:
  • 实际进入 Discourse Docker 容器并在那里安装 MySQL:
docker exec -it app bash
apt-get update && apt-get upgrade
# pv 仅用于方便显示进度,lsb-release 是某些东西必需的
apt-get install -y lsb-release pv mariadb-server mariadb-client libmariadb-dev
service mariadb start

请注意,MySQL 安装有点棘手,但 Mariadb 应该同样适用。

然后创建一个数据库:mysqlCREATE database phorum

然后从备份中填充它:pv phorum_db.sql.gz | gunzip | mysql phorum(如果你的转储是纯 sql,则不需要 gunzip)。

为 Ruby 添加 MySql 支持:

cd /var/www/discourse/
echo "gem 'mysql2'" >>Gemfile
bundle config unset deployment
bundle install --no-deployment

修改迁移脚本中的数据(数据库凭据、前缀、永久链接):

nano /var/www/discourse/script/import_scripts/phorum.rb

然后回到原始帖子的指南,一切都很好:

运行带有干净 Discourse 实例的导入器:

git config --global --add safe.directory /var/www/discourse
bundle exec ruby script/import_scripts/phorum.rb

如果你的 Discourse 数据库不是很干净,最好事先用 bundle exec rake db:drop db:create db:migrate 清理它。

如果出现“PG::ConnectionBad: connection to server on socket “/var/run/postgresql/.s.PGSQL.5432” failed: FATAL: Peer authentication failed for user “discourse” (PG::ConnectionBad)”错误:

  1. 如果你收到错误“‘Peer authentication failed for user “discourse”’”
  2. 编辑文件 /etc/postgresql/13/main/pg_hba.conf
  3. 将所有‘peer’更改为‘trust’并保存文件
  4. 重新加载 postgres 服务器:/etc/init.d/postgresql reload(或者可能是 psql -U postgres -c "SELECT pg_reload_conf();",但这有时对我不起作用)

首先运行用户迁移,这可能相对较慢(根据脚本输出,约为 1.2k 用户/分钟。我有 100k 用户,所以…)。然后它会创建类别并开始迁移消息和主题(速度相同,约 1.2k/分钟),但此时你已经可以访问网站并查看它的外观了。

对于像 Phorum 这样古老的引擎来说,这似乎比我预期的要顺畅得多。似乎没有迁移私人消息(PM),但这至少对我来说不是障碍。

再次感谢脚本和付出的努力!

要为如此复杂且涵盖所有步骤的内容编写指南非常困难。弄清楚某个特定用户可能需要被告知哪些部分很复杂。很高兴找到了另一份包含缺失部分的指南。

你或许可以包含 mysql 模板来安装 mysql,或者你也可以通过某种方式访问已安装的 mysql 服务器(我通常就是这么做的)。

如果你愿意,可以查看一些导入 PM 的其他脚本作为示例。