我的 phpBB 迁移之旅 (postgresql)

我在从 phpBB3 迁移到 discourse 的过程中分享我的发现。

解决方案包括:

  • postgres 源数据库
  • emoji
  • 调整导入器(修复引用错误,改进 bbcode 支持(包括 youtube),附件评论)
  • 软删除的帖子被导入为普通帖子

我非常挑剔,所以如果你跟着做,你应该能得到一个相当不错的结果。


我正在考虑从 phpbb(已安装版本历史:3.2.1 - 3.2.8)迁移到 discourse。
问题是,我使用 postgresql 作为数据库。有什么建议吗?我还没有尝试过,但假设它还没有得到支持,基于 OP。

新的导入脚本出来了吗?我看到那是在一年多以前。

1 个赞

批量导入脚本应该对您有用…… discourse/script/bulk_import/phpbb_postgresql.rb at 52d4de7b45eb1b7c7997da2ba8bff83a3c22a3a5 · discourse/discourse · GitHub

4 个赞

谢谢,@gerhard

我的理解正确吗?

  • script/import_scripts/phpbb3script/bulk_import 是完全独立的导入器
  • 批量导入器不太复杂(但速度更快),例如,它不会导入附件?

如果是这样,那么使用批量导入器似乎存在缺点……

那么没有其他解决方案了吗?是否建议探索从 PostgreSQL 迁移到 MySQL 或其他数据库?

2 个赞

是的,存在一些缺点。如果您熟悉 Ruby,我建议修改 discourse/script/import_scripts/phpbb3/database at main · discourse/discourse · GitHub 中的文件,使它们能与 pg gem 而不是 mysql2 一起工作。

也许吧?我不知道这有多容易,也不知道它是否真的能起作用。您可以试试……

1 个赞

真遗憾。好吧,我来试试。如果有什么发现,我会跟进。

2 个赞

那个导入器是会被弃用的吗?“新”导入器的状态如何?我正在考虑投入多少精力——这是否会有上游价值?

2 个赞

我没有亲自处理过从 PostgreSQL 到 MySQL 的问题,但纯粹从从 phpBB 迁移到 Discourse 的角度来看,我的意见是:不惜一切代价完成迁移。

我已经将两个 phpBB 论坛迁移到了 Discourse,虽然像任何改变一样,有一小部分用户会抱怨,但 Discourse 的好处是值得的!Discourse 不仅更容易维护和管理,而且其内置的用户参与度、图像处理、用户自定义和可读性等功能,都远远领先于 phpBB,根本无法与之相比。您还可以获得 Discourse 更好的支持。

我不是专家,但快速搜索一下,看起来您可以通过执行模式转储、更改模式语句中的数据类型以匹配 MySQL 使用的类型、使用修改后的模式在 MySQL 数据库中创建表,然后逐表执行 CSV 导出和导入来从 PostgreSQL 迁移到 MySQL。

一旦您有了 MySQL 数据库,您就可以使用常规的 phpBB 迁移脚本,并拥有所有附件。

这将是值得的!

3 个赞

如果你不注意数据库字符集和排序规则,这听起来就像是灾难的根源。

几年前我开始着手做这件事,但它未完成且已过时。不过,也许它会有帮助。

3 个赞

我并不是想暗示这会“很容易”,只是觉得它值得付出努力,甚至可以手动完成,而且似乎有很多资源可以完成它,包括自动化工具和手动方法。:grinning:

3 个赞

鉴于我讨厌 Ruby,并且现有的导入器将被弃用,转而使用批量导入器(这还不足以满足我的需求),我将继续采用 PostgreSQL → MySQL 迁移策略。

我正在使用 MySQL Workbench 的迁移向导取得一些进展。如果成功,我将写一篇简短的指南,但到目前为止,它看起来很有希望。

2 个赞

到目前为止,我一直被这个问题困扰:

https://bugs.mysql.com/bug.php?id=89048

基本上,MySQL Workbench 在导入 Unicode 时会失败。明天我会尝试使用 MariaDB,看看是否可以在导入前设置默认数据库编码之类的。

1 个赞

如果 MySQL Workbench 能正常工作那就太好了。我在查看选项时看到了很多关于它的错误报告,所以我没有推荐它。

我之前提到过模式转储和 CSV 导出/导入方法,我只会再说一次,并稍作修改,使其更容易,然后就不再提了。

如果你想走 GUI 路线:

  1. 获取一个与你正在使用的 phpBB3 版本相同、正在运行 MySQL/MariaDB 的工作副本的、所有表的仅结构导出。从大多数运行 MySQL/MariaDB 的网络主机上都可以找到的 phpMyAdmin 中创建一个,这只需要两分钟。(或者,如果你找不到人帮你进行仅结构导出,你也可以从 phpBB3 安装脚本中获取所需的 CREATE TABLE 语句,甚至可以使用一个廉价的网络托管账户在 MySQL/MariaDB 环境中安装你的 phpBB3 版本,然后删除它创建的表中的数据,以创建一个空的 MySQL/MariaDB 数据库。)
  2. 找到一个带有 MySQL/MariaDB 和 phpMyAdmin 的网络主机,创建数据库,使用 phpMyAdmin 从你在步骤 1 中创建的仅结构导出导入结构。
  3. 从你的 postgresql 数据库为每个表创建一个 CSV 导出,并使用 phpMyAdmin 将其导入到你的新 MySQL/MariaDB 数据库中的相应表中。

我认为这将避免任何字符集和编码问题,而且你不需要弄清楚手动转换 postgre 的模式转储所需的所有相应数据类型和字段大小。

我可以给你一个仅结构的 SQL 语句,但我仍然拥有的唯一数据库来自 phpBB3 3.3.8,所以如果你使用的是 v. 3.2.x,它可能会带来更多问题。

3 个赞

哈哈。是的,我花了些不显眼的技巧才让它勉强能用。我认为它仍然可以用,但感谢你给了我另一个探索的途径。

1 个赞

好的,呼。这是我的 PostgreSQL 导入解决方案。

这将把你的 PostgreSQL 转储转换为一个可以插入导入器的可运行的 MariaDB 服务器。需要 Docker Compose。

它适用于 phpBB 3.2。不确定 3.3。如果你非常需要 3.3 支持,如果你给我一个 phpBB 3.3 的 pg_dumpall 转储,我可以尝试修复它。

3 个赞

phpbb_smilies.zip (87.2 KB)

(与默认表情符号进行比较)

供参考,这是我的表情符号解决方案

我提供了两个选项:

  1. 原生
    • 如果您不想保留原始的 phpBB 表情符号,可以将它们映射到 discourse 中已有的原生表情符号

:grin: :smile: :wink: :slightly_frowning_face: :astonished: :exploding_head: :confounded: :sunglasses: :joy: :rage:
:stuck_out_tongue: :person_facepalming: :sob: :imp: :smiling_imp: :roll_eyes: :exclamation: :question: :bulb: :arrow_forward:
:neutral_face: :smiley_cat: :nerd_face: :nerd_face:

  1. 导入
    • 如果您想保留原始的 phpBB 表情符号并使它们可用作短代码以便继续使用
      • 在运行导入器之前,转到 discourse 管理后台的表情符号部分(admin/customize/emojis
      • 如果需要,可以先创建一个名为 phpbb 或其他名称的表情符号组
      • new_files 中的表情符号文件(一次 5 个)拖放到浏览器中,将它们导入为自定义表情符号

我提供了一个 zip 文件,其中包含两个选项的配置,作为 import.yml 包含在 zip 文件中。

zip 文件中还有一个电子表格,可以帮助您决定或创建自己的映射:

phpbb_smilies
├── phpbb_smilies.xlsx # 主参考,帮助您决定
├── import.yml # 包含两个选项的配置文件
├── orig_phpbb_smilies.csv # 原始 phpBB 数据
├── orig_files # 原始 phpBB 表情符号文件
│   ├── icon_arrow.gif
│   └── ...
└── new_files # 已重命名以匹配电子表格中 `new_shortcode` 列的表情符号文件
    ├── phpbb_arrow.gif
    └── ...
1 个赞

有人成功设置了引用归属吗?

这是 phpbb 中包含引用的原始帖子的示例(用户名和内容已更改,ID 等相同)

[quote=someuser post_id=46649 time=1677556325 user_id=48]
foo
[/quote]

bar

这是它在 discourse 中的样子:

这是迁移到 discourse 的原始帖子:

[quote=", post:37, topic:1893"]
foo
[/quote]

bar

迁移后的 postid 和 topicid 是正确的,但缺少用户名。这导致它无法交互。当用户名为空字符串时,引用不会展开,并且您无法单击它来跟踪对原始帖子的引用。

在不改进导入器的情况下,我能期待更好的体验吗?也就是说,是我做错了什么吗?

1 个赞

我相当确定,在我上个月进行的 phpbb3 导入中,这些都正常工作。

1 个赞

我还没有解决最后一个问题,但这是另一个问题。

我注意到导入完成后,您启动应用程序容器时,我仍然存在的 phpbb 服务器会受到严重影响。我认为这发生在 sidekiq 后处理阶段。

phpbb 仍然存在于 www.example.com,而 discourse 存在于 dc.example.com

我试图了解实际发生了什么,在测试迁移期间哪些设置是合理的,以及在最终迁移中哪些设置是合理的。以及我是否需要让 phpbb 运行以进行 sidekiq 后处理。提问是因为我不知道后处理中会发生什么。

我当前 settings.yml 中一些可能相关的设置:

import:
  # 如果您将多个 phpBB 论坛导入到单个 Discourse 论坛,请设置此项。
  site_name:
  site_prefix:
    # 这是重写帖子中内部链接所必需的
    original: example.com    # 不带 http(s)://
    new: https://dc.example.com       # 带 http:// 或 https://

如果还有其他需要查看的内容,请告诉我。

另一件我不清楚的事情是 www 子域名。我目前使用 nginx 为 phpbb 重定向到 www。所以在上面的例子中,将 original: example.comoriginal: www.example.com 相比,是否重要?对于最终迁移中的 new 也有类似的问题。我的用户实际上将从 www.example.com 访问 discourse,但我不知道最佳实践是什么。

1 个赞

引文解析确实有问题。
我刚刚尝试导入一个全新安装的 phpBB 3.2.8(安装在 mariadb 上)。
引文归属已损坏——导入的引文中用户名字段为空,但其他一切都合法。
导入帖子的 Discourse 截图:


Discourse 导入的帖子:

[quote=", post:4, topic:12"]
[quote=", post:3, topic:12"]
[quote=", post:2, topic:12"]
msg 1
[/quote]

second
[/quote]

third
[/quote]

fourth

原始 phpbb 帖子:

MariaDB [phpbb]> select post_text from phpbb_posts where post_id=5;
...
| <r><QUOTE author="admin" post_id="4" time="1678400691" user_id="2"><s >[quote=admin post_id=4 time=1678400691 user_id=2]</s>
<QUOTE author="admin" post_id="3" time="1678400685" user_id="2"><s >[quote=admin post_id=3 time=1678400685 user_id=2]</s>
<QUOTE author="admin" post_id="2" time="1678400675" user_id="2"><s >[quote=admin post_id=2 time=1678400675 user_id=2]</s>msg 1</e>[/quote]</e></QUOTE>

second

</e>[/quote]</e></QUOTE>

third

</e>[/quote]</e></QUOTE>

fourth</r> |

也许我最终还是会改进导入器……

3 个赞

已修复


我对论坛的迁移比较挑剔,因此我将继续改进导入器。不确定我是否会费心制作 PR,因为导入器已弃用,而且我的一些修复程序是针对我的论坛半定制的,但如果有人需要,此分支将包含我所有的修复程序:

我修复了引用问题,添加了对一些常用 bbcode 的支持,改进了 youtube 链接解析的错误,并支持 mentions/simplementions 扩展。我还有更多需要改进的地方,例如添加对多个站点前缀的支持(主要用例是当您的论坛上有指向 example.comwww.example.com 的链接时)。

即使我支持一些非标准的东西,在没有扩展的标准 phpBB 论坛上运行它应该也没有问题。我建议无论如何都使用我的。

使用它的最简单方法是将我的分支拉取到某个地方,然后使用绑定挂载覆盖容器内的导入脚本目录。

例如,在某处拉取我的更改:

git clone --filter=blob:none --no-checkout https://github.com/ftc2/discourse.git discourse_dev
cd discourse_dev
git sparse-checkout set --cone
git switch phpbb_import
git sparse-checkout set script/import_scripts

然后将此添加到您的 import.yml 容器配置中:

docker_args:
  - '-v /path/to/discourse_dev/script/import_scripts:/var/www/discourse/script/import_scripts'

然后重新构建导入容器。重新构建后,您可能需要重置您拉取我的仓库的位置,因为构建过程会覆盖我的文件,哈哈。

cd /path/to/discourse_dev
git reset --hard HEAD
chown -R 1000:1000 .
5 个赞