我的 phpBB 迁移之旅 (postgresql)

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

解决方案包括:

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

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


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

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

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

谢谢,@gerhard

我的理解正确吗?

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

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

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

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

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

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

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

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

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

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

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

这将是值得的!

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

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

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

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

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

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

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

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

如果 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,它可能会带来更多问题。

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

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

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

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

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
    └── ...

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

这是 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 是正确的,但缺少用户名。这导致它无法交互。当用户名为空字符串时,引用不会展开,并且您无法单击它来跟踪对原始帖子的引用。

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

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

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

我注意到导入完成后,您启动应用程序容器时,我仍然存在的 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,但我不知道最佳实践是什么。

引文解析确实有问题。
我刚刚尝试导入一个全新安装的 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> |

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

已修复


我对论坛的迁移比较挑剔,因此我将继续改进导入器。不确定我是否会费心制作 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 .