Напрямую запись в базу данных

Кто-нибудь здесь уже занимался прямой работой с базой данных на чтение/запись? Сначала я пытался использовать API для создания тем и сообщений, но это оказалось слишком ненадежно, поэтому теперь я рассматриваю возможность прямой записи в базу данных.

Данные, которые я хочу добавить, довольно просты: для тем (заголовок темы, автор, категория, текст) и для сообщений (автор, текст).

Однако я подозреваю, что необходимо заполнить и различные дополнительные поля, а также, возможно, выполнять запросы к базе данных пользователей.

Я начинаю с нуля, поэтому хотел бы узнать, делал ли кто-то это раньше, или получить советы по структуре таблиц или на что следует обратить внимание.

Я забыл, что мне также нужно добавить дату/время к каждому сообщению (я не могу отредактировать свой исходный пост для обновления).

Можете рассказать о возникших проблемах?

Вы можете увидеть мои другие сообщения. Они касались:

  • Проблем с лимитом запросов
  • Проблем валидации
  • Нестабильной работы обхода валидации для потоков по сравнению с темами

В итоге я решил, что проще обратиться напрямую к базе данных.

Вместо часов разочарований из-за капризов 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());

Получите новый идентификатор, в моём случае это 886.

Затем вставьте сообщения:

insert into posts (user_id, topic_id, post_number, raw, cooked, created_at, updated_at, last_version_at) values (1,886,1,'это исходный текст','это обработанный тест',NOW(),NOW(),NOW());

Затем обновите posts_count (если это ещё не было сделано при вставке темы). Обратите внимание, что, похоже, для тела темы требуется начальное сообщение. Ниже приведён пример изменения количества сообщений в теме на 1:

update topics set posts_count=2 where id=886;

Вероятно, потому что вы используете другую учётную запись?

Я рекомендую вам разобраться, как использовать API. Rails берет на себя множество «магических» операций. Высока вероятность, что вы совершите действие, которое сделает вашу базу данных неработоспособной.

Но видите ли вы какие-либо проблемы, если вы просто добавляете записи в таблицы тем и сообщений, и они корректно сформированы?

Это ужасная идея.

Почему вы думаете, что это проще, чем использовать API или запускать команды Rails для создания постов?

Я не знал о существовании команд Rails для создания постов. Можете ли вы предоставить дополнительные детали по этому поводу?

Да, подробности таковы: Discourse — это приложение на Ruby on Rails!

Я знаю, что Discourse — это приложение на Rails. Но вы сказали:

То есть вы подразумеваете, что есть другой способ создания тем путём выполнения «команд Rails», если только под командой Rails вы не имеете в виду ручное создание учётных записей и ввод их через веб-интерфейс Discourse?

Хорошей практикой является использование API, особенно если вы делаете вызов извне приложения, так как он берет на себя всю аутентификацию и авторизацию, а также значительную часть бизнес-логики, которую нельзя всегда предполагать.

Хорошо, одна из вещей, которую я хочу сделать, — это обойти всю авторизацию и внести сообщение в базу данных, не допуская сбоев из-за того, что у пользователя нет прав на публикацию в категории, тема слишком короткая или недостаточно энтропии и т. д.

Было бы здорово, если бы существовал вызов API «суперпользователя», который обходил бы все эти проверки и просто создавал бы сообщение или тему.

Например, если вы хотите использовать API для создания темы от имени пользователя, у которого в данный момент нет прав на публикацию в определённой категории, вы можете использовать параметр bypass_validations для этого. Однако, когда вы затем вызываете API для создания ответа от того же пользователя, проверки валидации не пропускаются, и создание ветки не удаётся. (это ошибка, о которой сообщалось 6 лет назад, и был представлен pull request с исправлением, который так и не был включён в кодовую базу).

Кроме того, в этом случае, в отличие от прямого внесения данных в базу данных, нет поддержки транзакций для отката создания исходной ветки, и вам приходится вручную находить её, чтобы очистить и исправить.

Пока что простое вставка постов/тем работает нормально. Я немного беспокоился по поводу колонки ‘cooked’, так как она не может быть пустой, но пока я просто заполняю её тем же текстом, что и в ‘raw’, оставляя baked_at и baked_version пустыми.

При просмотре процесс выпечки, похоже, запускается довольно быстро.

Хорошо. Я нашел способ запустить повторную выпечку:

rake posts:rebake

Используйте спецификации и скрипты импорта в качестве руководства для манипулирования структурами данных дискурса с помощью команд Ruby.

Для экспериментов используйте консоль Rails.

Стоит отметить, что если ваш клиент написан на Ruby, вы можете использовать Ruby API gem:

Если вы создадите запись через Rails, перевыпечка будет выполнена автоматически при сохранении поста, а также будут отправлены уведомления и выполнено множество других действий.

Когда пост создается через прямой доступ к базе данных, Discourse, по-видимому, также сразу же переформатирует его.