Escrevendo diretamente ao banco de dados

Alguém aqui já trabalhou para ler/escrever diretamente do banco de dados? No início, tentei usar a API para criar threads e posts, mas isso foi muito pouco confiável, então agora estou pensando em tentar escrever diretamente no banco de dados.

Os dados que quero inserir são bem simples: (título da thread, autor, categoria, texto do corpo) e para posts (autor, texto do corpo).

No entanto, suspeito que vários campos adicionais também precisem ser preenchidos e talvez consultas ao banco de dados de usuários.

Começarei do zero, então estou vendo se alguém já fez isso antes ou tem alguma dica sobre as estruturas das tabelas ou qualquer coisa a ser observada.

Eu esqueci que também preciso adicionar a data/hora a cada um (não consigo editar minha postagem original para atualizar).

Você poderia compartilhar os problemas que encontrou?

2 curtidas

Você pode ver minhas outras postagens. Elas eram sobre:

  • Problemas de limite de taxa
  • Problemas de validação
  • Bypass de validação não funcionando consistentemente para threads vs tópicos

No final, pensei que seria mais fácil ir direto ao banco de dados.

Em vez de horas de frustração tentando lidar com as complexidades da API, em poucos minutos consegui fazer algo funcionar e, espero, mais performático:

Para aqueles que desejam fazer o mesmo, anotações da minha exploração até agora:

Primeiro, entre no contêiner:

sudo ./launcher enter app

Em seguida, conecte-se ao banco de dados:

sudo -u postgres psql discourse

Para inserir um tópico:
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());

Obtenha o novo id, no meu caso 886.

Em seguida, insira posts:

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());

Em seguida, atualize posts_count (se ainda não foi feito na inserção do tópico). Observe que parece que o corpo do tópico precisa de um post inicial. Abaixo, altera o número de posts do tópico para 1:

update topics set posts_count=2 where id=886;

Provavelmente porque você está em uma conta diferente?

3 curtidas

Recomendo que você descubra como usar a API. Muita mágica é tratada pelo Rails. A probabilidade de você fazer algo que torne seu banco de dados inutilizável é alta.

5 curtidas

Mas você vê algo que pode dar errado se você estiver apenas adicionando às tabelas de tópicos e postagens e elas estiverem corretamente formatadas?

Esta é uma ideia terrível.

Por que você acha que isso é mais fácil do que usar a API ou executar comandos do Rails para criar posts?

5 curtidas

Eu não sabia sobre comandos do Rails para criar posts. Você tem mais detalhes sobre isso?

Sim, os detalhes são: Discourse é um aplicativo Rails!

1 curtida

Estou ciente de que o Discourse é um aplicativo Rails. Mas você disse:

Então, implicando que há outra maneira de gerar threads emitindo ‘comandos rails’, a menos que por comando rails você queira dizer criar manualmente contas e digitá-las na interface web do discourse?

É uma boa prática usar a API, especialmente se você estiver fazendo uma chamada de fora do aplicativo, pois ela cuida de toda a autenticação e autorização, bem como de muita lógica de negócios que você nem sempre pode presumir.

2 curtidas

Bem, uma das coisas que quero fazer é contornar toda a autorização e inserir a postagem no banco de dados sem que ela falhe porque um usuário não tem permissão para postar em uma categoria, ou o tópico é muito curto, ou não há entropia suficiente, etc., etc.

Seria bom se houvesse uma chamada de API de ‘superusuário’ que contornasse todas essas verificações e simplesmente criasse a postagem ou o tópico.

Por exemplo, se você quiser usar a API para criar um tópico sob um usuário que atualmente não tem permissão para postar em uma determinada categoria, você pode usar o parâmetro bypass_validations para fazer isso. Mas quando você chama a API para criar uma resposta pelo mesmo usuário, as verificações de validação não são ignoradas e a criação do tópico falha. (este é um bug que foi relatado há 6 anos com um pull request para uma correção que nunca entrou na base de código).

Além disso, neste caso, ao contrário de escrever diretamente no banco de dados, não há suporte para transações para reverter a criação do tópico original e você tem que encontrá-lo manualmente para limpá-lo e corrigi-lo.

Por enquanto, apenas inserir as postagens/tópicos parece funcionar bem. Eu estava um pouco preocupado com a coluna ‘cooked’, pois não era possível deixá-la nula, mas estou apenas preenchendo-a com o mesmo texto que ‘raw’ por enquanto e deixando ‘baked_at’ e ‘baked_version’ como NULL.

Na visualização, o processo de cozimento parece ser acionado rapidamente quando a postagem é visualizada.

OK. Encontrei uma maneira de acionar o re-cozimento:

rake posts:rebake

Use especificações e scripts de importação como guia para manipular estruturas de dados do discourse via comandos ruby.

Use o console rails para experimentos.

3 curtidas

Vale a pena notar que se o seu cliente for escrito em Ruby, você pode usar a gem da API Ruby:

1 curtida

Se você criar o registro com o Rails, ele fará o rebake automaticamente quando a postagem for salva, além de enviar notificações e um monte de outras coisas.

Quando a postagem é criada com acesso bruto ao banco de dados, o Discourse também parece reprocessá-la imediatamente.

1 curtida