直接写入数据库

有人在这里已经做过直接读写数据库的工作了吗?起初我尝试使用 API 来创建帖子和回复,但这太不可靠了,所以我现在正在研究直接写入数据库。\n\n我想输入的数据很简单:(帖子标题、作者、类别、正文) 和 (作者、正文)。\n\n但是,我怀疑还需要填写各种其他字段,并且可能需要查找用户数据库。\n\n我将从零开始,所以想看看是否有人以前做过,或者对表结构或需要注意的事项有什么建议。

我忘记了还需要为每个帖子添加日期/时间(我无法编辑原始帖子进行更新)。

您能分享一下您遇到的问题吗?

2 个赞

您可以看到我的其他帖子。它们是关于:

  • 速率限制问题
  • 验证问题
  • 针对线程与主题的验证绕过未能持续生效

最后,我认为直接访问数据库会更容易。

与其花费数小时的挫败感来处理 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;

很可能是因为您使用的是不同的账户?

3 个赞

我建议你弄清楚如何使用 API。Rails 会处理很多魔法。你很有可能会做出一些导致数据库无法使用的操作。

5 个赞

但是,如果您只是向主题和帖子表添加内容,并且它们格式正确,您会看到任何可能出错的地方吗?

这是一个糟糕的主意。

你为什么认为这比使用 API 或运行 Rails 命令创建帖子更容易?

5 个赞

我不知道有创建帖子的 rails 命令。您有这方面的详细信息吗?

是的,详情是:Discourse 是一个 Rails 应用!

1 个赞

我知道 Discourse 是一个 Rails 应用。但你说过:

所以你暗示还有另一种通过发出“rails 命令”来生成帖子的方法,除非你所说的 rails 命令是指手动创建账户并在 Discourse 网页前端输入它们?

从应用外部调用 API 是一种良好的实践,因为它能处理所有的身份验证和授权,以及许多你无法完全确定的业务逻辑。

2 个赞

嗯,我想做的一件事是绕过所有授权,将帖子直接存入数据库,而不必因为用户没有权限发布到某个类别,或者主题太短,或者熵不足等等而失败。

如果有一个“超级用户”API调用,可以绕过所有这些检查,直接创建帖子或主题,那就太好了。

例如,如果你想使用API在当前没有权限在某个类别中发帖的用户下创建一个主题,你可以使用bypass_validations参数来实现。但是,当你随后调用API让同一个用户创建回复时,验证检查不会被跳过,主题创建会失败。(这是一个6年前报告的bug,有一个修复的拉取请求,但从未合并到代码库中)。

此外,在这种情况下,与直接写入数据库不同,不支持事务来回滚原始主题的创建,你必须手动找到它来清理和修复它。

目前,仅插入帖子/主题似乎效果尚可。我有点担心“cooked”列,因为它不能为 null,但目前我只是用与 raw 相同的文本填充它,并将 baked_at 和 baked_version 留空。

在查看时,烘焙过程似乎在帖子被查看时很快被触发。

好的。我找到了触发重新烘焙的方法:

rake posts:rebake

使用规范和导入脚本作为指南,通过 Ruby 命令操作 Discourse 数据结构。

使用 Rails 控制台进行实验。

3 个赞

值得指出的是,如果您的客户端是用 Ruby 编写的,您可以使用 Ruby API gem:

1 个赞

如果你用 Rails 创建记录,它会在保存帖子时自动执行重新烘焙,同时发送通知和一堆其他东西。

当使用原始数据库访问创建帖子时,Discourse 似乎也会立即对其进行重新烘焙。

1 个赞