Scrittura direttamente al database

Qualcuno qui ha già lavorato per leggere/scrivere direttamente dal database? All’inizio ho provato a usare l’API per creare thread e post, ma era troppo inaffidabile, quindi ora sto cercando di scrivere direttamente nel database.

I dati che voglio inserire sono piuttosto semplici: (titolo del thread, autore, categoria, testo del corpo) e per i post (autore, testo del corpo).

Tuttavia, sospetto che debbano essere completati anche vari campi aggiuntivi e forse effettuate delle ricerche nel database degli utenti.

Inizierò da zero, quindi sto cercando di vedere se qualcuno l’ha già fatto o ha qualche suggerimento sulle strutture delle tabelle o su eventuali cose a cui prestare attenzione.

Dimenticavo anche di aggiungere la data/ora a ciascuno (non riesco a modificare il mio post originale per aggiornarlo).

Potresti condividere i problemi che hai riscontrato?

2 Mi Piace

Puoi vedere i miei altri post. Riguardavano:

  • Problemi di rate limiting
  • Problemi di validazione
  • La bypass della validazione non funziona in modo coerente per thread vs argomenti

Alla fine, ho pensato che sarebbe stato più facile andare direttamente al database.

Invece di ore di frustrazione cercando di affrontare le stranezze dell’API, in pochi minuti sono riuscito a far funzionare qualcosa e spero che sia più performante:

Per coloro che desiderano fare lo stesso, note dalla mia esplorazione finora:

Per prima cosa entra nel container:

sudo ./launcher enter app

Quindi connettiti al database:

sudo -u postgres psql discourse

Per inserire un argomento:
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());

Ottieni il nuovo id, nel mio caso 886.

Quindi inserisci i post:

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

Quindi aggiorna posts_count (se non già fatto all’inserimento dell’argomento). Nota che sembra che il corpo dell’argomento necessiti di un post iniziale. Di seguito viene modificato il numero di post dell’argomento in 1:

update topics set posts_count=2 where id=886;

Probabilmente perché sei su un account diverso?

3 Mi Piace

Ti consiglio di capire come usare l’API. Molta “magia” viene gestita da Rails. La probabilità che tu faccia qualcosa che renda il tuo database inutilizzabile è alta.

5 Mi Piace

Ma vedi qualcosa che potrebbe andare storto se stessi solo aggiungendo alle tabelle di argomenti e post e fossero formate correttamente?

Questa è un’idea terribile.

Perché pensi che sia più facile che usare l’API o eseguire comandi Rails per creare post?

5 Mi Piace

Non ero a conoscenza dei comandi rails per creare post. Hai ulteriori dettagli in merito?

Sì, i dettagli sono: Discourse è un’app Rails!

1 Mi Piace

Sono consapevole che Discourse è un’app Rails. Ma tu hai detto:

Quindi implicando che c’è un altro modo di generare thread emettendo ‘comandi rails’ a meno che per comando rails tu non intenda creare manualmente account e digitarli nell’interfaccia web di discourse?

È buona norma utilizzare l’API, soprattutto se si effettua una chiamata dall’esterno dell’app, perché si occupa di tutta l’autenticazione e l’autorizzazione, nonché di gran parte della logica di business che non si può sempre dare per scontata.

2 Mi Piace

Bene, una delle cose che voglio fare è bypassare tutte le autorizzazioni e inserire il post nel database senza che venga bloccato perché un utente non ha il permesso di pubblicare in una categoria, o l’argomento è troppo corto, o non c’è abbastanza entropia, ecc. ecc.

Sarebbe bello se ci fosse una chiamata API ‘superuser’ che bypassasse tutti questi controlli e creasse semplicemente il post o l’argomento.

Ad esempio, se si desidera utilizzare l’API per creare un argomento sotto un utente che attualmente non ha il permesso di pubblicare in una determinata categoria, è possibile utilizzare il parametro bypass_validations per farlo. Ma quando si chiama l’API per creare una risposta dallo stesso utente, i controlli di validazione non vengono saltati e la creazione del thread fallisce. (questo è un bug segnalato 6 anni fa con una pull request per una correzione che non è mai entrata nel codebase).

Inoltre, in questo caso, a differenza della scrittura diretta nel database, non c’è supporto per le transazioni per annullare la creazione del thread originale e devi trovarlo manualmente per pulirlo e correggerlo.

Per ora, inserire i post/argomenti sembra funzionare bene. Ero un po’ preoccupato per la colonna ‘cooked’ poiché non era possibile averla null, ma per ora la sto riempiendo con lo stesso testo di ‘raw’ e lasciando ‘baked_at’ e ‘baked_version’ NULL.

Alla visualizzazione, il processo di baking sembra essere attivato abbastanza rapidamente quando il post viene visualizzato.

OK. Ho trovato un modo per attivare il rebake:

rake posts:rebake

Usa le specifiche e importa gli script come guida per manipolare le strutture dati di discourse tramite comandi ruby.

Usa la console rails per gli esperimenti.

3 Mi Piace

Vale la pena sottolineare che se il tuo client è scritto in Ruby puoi usare la gemma API Ruby:

1 Mi Piace

Se crei il record con Rails, farà automaticamente il rebake quando il post viene salvato, oltre a inviare notifiche e un sacco di altre cose.

Quando il post viene creato con accesso diretto al database, Discourse sembra anche ribatterlo immediatamente.

1 Mi Piace