有人在这里已经做过直接读写数据库的工作了吗?起初我尝试使用 API 来创建帖子和回复,但这太不可靠了,所以我现在正在研究直接写入数据库。\n\n我想输入的数据很简单:(帖子标题、作者、类别、正文) 和 (作者、正文)。\n\n但是,我怀疑还需要填写各种其他字段,并且可能需要查找用户数据库。\n\n我将从零开始,所以想看看是否有人以前做过,或者对表结构或需要注意的事项有什么建议。
我忘记了还需要为每个帖子添加日期/时间(我无法编辑原始帖子进行更新)。
您能分享一下您遇到的问题吗?
您可以看到我的其他帖子。它们是关于:
- 速率限制问题
- 验证问题
- 针对线程与主题的验证绕过未能持续生效
最后,我认为直接访问数据库会更容易。
与其花费数小时的挫败感来处理 API 的反复无常,不如在几分钟内就设法让一些东西工作起来,并且可能性能更好:
对于那些想做同样事情的人,以下是我到目前为止探索的笔记:
首先进入容器:
sudo ./launcher enter app
然后连接到数据库:
sudo -u postgres psql discourse
插入一个主题:
insert into topics (title, user_id, archetype, fancy_title, category_id, created_at, updated_at, last_post_user_id, bumped_at) values ('psql test', 1, 'regular', 'psql test',8, NOW(), NOW(), 1, NOW());
获取新的 id,以我为例是 886。
然后插入帖子:
insert into posts (user_id, topic_id, post_number, raw, cooked, created_at, updated_at, last_version_at) values (1,886,1,'this is the raw text','this is the cooked test',NOW(),NOW(),NOW());
然后更新 posts_count(如果在主题插入时未完成)。请注意,主题正文似乎需要一个初始帖子。以下是将主题的帖子数更改为 1:
update topics set posts_count=2 where id=886;
很可能是因为您使用的是不同的账户?
我建议你弄清楚如何使用 API。Rails 会处理很多魔法。你很有可能会做出一些导致数据库无法使用的操作。
但是,如果您只是向主题和帖子表添加内容,并且它们格式正确,您会看到任何可能出错的地方吗?
这是一个糟糕的主意。
你为什么认为这比使用 API 或运行 Rails 命令创建帖子更容易?
我不知道有创建帖子的 rails 命令。您有这方面的详细信息吗?
是的,详情是:Discourse 是一个 Rails 应用!
我知道 Discourse 是一个 Rails 应用。但你说过:
所以你暗示还有另一种通过发出“rails 命令”来生成帖子的方法,除非你所说的 rails 命令是指手动创建账户并在 Discourse 网页前端输入它们?
从应用外部调用 API 是一种良好的实践,因为它能处理所有的身份验证和授权,以及许多你无法完全确定的业务逻辑。
嗯,我想做的一件事是绕过所有授权,将帖子直接存入数据库,而不必因为用户没有权限发布到某个类别,或者主题太短,或者熵不足等等而失败。
如果有一个“超级用户”API调用,可以绕过所有这些检查,直接创建帖子或主题,那就太好了。
例如,如果你想使用API在当前没有权限在某个类别中发帖的用户下创建一个主题,你可以使用bypass_validations参数来实现。但是,当你随后调用API让同一个用户创建回复时,验证检查不会被跳过,主题创建会失败。(这是一个6年前报告的bug,有一个修复的拉取请求,但从未合并到代码库中)。
此外,在这种情况下,与直接写入数据库不同,不支持事务来回滚原始主题的创建,你必须手动找到它来清理和修复它。
目前,仅插入帖子/主题似乎效果尚可。我有点担心“cooked”列,因为它不能为 null,但目前我只是用与 raw 相同的文本填充它,并将 baked_at 和 baked_version 留空。
在查看时,烘焙过程似乎在帖子被查看时很快被触发。
好的。我找到了触发重新烘焙的方法:
rake posts:rebake
使用规范和导入脚本作为指南,通过 Ruby 命令操作 Discourse 数据结构。
使用 Rails 控制台进行实验。
值得指出的是,如果您的客户端是用 Ruby 编写的,您可以使用 Ruby API gem:
如果你用 Rails 创建记录,它会在保存帖子时自动执行重新烘焙,同时发送通知和一堆其他东西。
当使用原始数据库访问创建帖子时,Discourse 似乎也会立即对其进行重新烘焙。