Direktes Schreiben in die Datenbank

Hat hier schon jemand daran gearbeitet, direkt aus der Datenbank zu lesen/schreiben? Zuerst habe ich versucht, die API zum Erstellen von Threads und Beiträgen zu verwenden, aber das war zu unzuverlässig, also versuche ich jetzt, direkt in die Datenbank zu schreiben.

Die Daten, die ich einfügen möchte, sind recht einfach: (Thread-Titel, Autor, Kategorie, Textkörper) und für Beiträge (Autor, Textkörper).

Ich vermute jedoch, dass verschiedene zusätzliche Felder ausgefüllt und möglicherweise Nachschlagevorgänge in der Benutzerdatenbank durchgeführt werden müssen.

Ich fange bei Null an und suche nach jemandem, der es schon einmal gemacht hat oder Hinweise zu den Tabellenstrukturen oder Dingen gibt, auf die man achten sollte.

Ich habe vergessen, dass ich auch Datum/Uhrzeit zu jedem hinzufügen muss (ich kann meinen ursprünglichen Beitrag nicht bearbeiten, um ihn zu aktualisieren).

Könnten Sie die aufgetretenen Probleme mitteilen?

2 „Gefällt mir“

Sie können meine anderen Beiträge sehen. Sie bezogen sich auf:

  • Probleme mit der Ratenbegrenzung
  • Validierungsprobleme
  • Validierungs-Bypass funktioniert nicht konsistent für Threads vs. Themen

Am Ende dachte ich, es wäre einfacher, direkt auf die Datenbank zuzugreifen.

Anstatt stundenlanger Frustration, um mit den Unwägbarkeiten der API fertig zu werden, habe ich in wenigen Minuten etwas zum Laufen gebracht, das hoffentlich performanter ist:

Für diejenigen, die dasselbe tun möchten, Notizen aus meiner bisherigen Erkundung:

Betreten Sie zuerst den Container:

sudo ./launcher enter app

Verbinden Sie sich dann mit der Datenbank:

sudo -u postgres psql discourse

Um ein Thema einzufügen:
insert into topics (title, user_id, archetype, fancy_title, category_id, created_at, updated_at, last_post_user_id, bumped_at) \nvalues ('psql test', 1, 'regular', 'psql test',8, NOW(), NOW(), 1, NOW());

Holen Sie sich die neue ID, in meinem Fall 886.

Fügen Sie dann Beiträge ein:
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());

Aktualisieren Sie dann posts_count (falls nicht bereits beim Einfügen des Themas geschehen). Beachten Sie, dass der Thema-Körper anscheinend einen anfänglichen Beitrag benötigt. Unten wird die Anzahl der Beiträge des Themas auf 1 geändert:

update topics set posts_count=2 where id=886;

Wahrscheinlich, weil Sie ein anderes Konto verwenden?

3 „Gefällt mir“

Ich empfehle Ihnen, herauszufinden, wie Sie die API verwenden. Viel Magie wird von Rails gehandhabt. Die Wahrscheinlichkeit, dass Sie etwas tun, das Ihre Datenbank unbrauchbar macht, ist hoch.

5 „Gefällt mir“

Aber sehen Sie etwas, das schiefgehen könnte, wenn Sie nur Themen und Beitragstabellen hinzufügen und diese korrekt gebildet sind?

Das ist eine schreckliche Idee.

Warum glaubst du, dass das einfacher ist, als entweder die API zu verwenden oder Rails-Befehle auszuführen, um Beiträge zu erstellen?

5 „Gefällt mir“

Ich war mir nicht bewusst, dass es Rails-Befehle zum Erstellen von Beiträgen gibt. Haben Sie weitere Details dazu?

Ja, die Details sind: Discourse ist eine Rails-App!

1 „Gefällt mir“

Mir ist bewusst, dass Discourse eine Rails-App ist. Aber Sie sagten:

Also implizieren Sie, dass es eine andere Möglichkeit gibt, Threads zu generieren, indem Sie ‘Rails-Befehle’ ausgeben, es sei denn, Sie meinen mit Rails-Befehl das manuelle Erstellen von Konten und das Eingeben in das Discourse-Web-Frontend?

Es ist eine gute Praxis, die API zu verwenden, insbesondere wenn Sie einen Aufruf von außerhalb der App aus tätigen, da sie die gesamte Authentifizierung und Autorisierung sowie viel Geschäftslogik übernimmt, die man nicht immer voraussetzen kann.

2 „Gefällt mir“

Nun, eines der Dinge, die ich tun möchte, ist, die gesamte Autorisierung zu umgehen und den Beitrag in die Datenbank zu schreiben, ohne dass er fehlschlägt, weil ein Benutzer keine Berechtigung hat, in eine Kategorie zu posten, oder das Thema zu kurz ist, oder nicht genug Entropie vorhanden ist usw. usw.

Es wäre schön, wenn es einen „Superuser“-API-Aufruf gäbe, der all diese Prüfungen umgeht und einfach den Beitrag oder das Thema erstellt.

Wenn Sie beispielsweise die API verwenden möchten, um ein Thema unter einem Benutzer zu erstellen, der derzeit keine Berechtigung hat, in einer bestimmten Kategorie zu posten, können Sie den Parameter bypass_validations verwenden, um dies zu tun. Wenn Sie dann jedoch die API aufrufen, um eine Antwort desselben Benutzers zu erstellen, werden die Validierungsprüfungen nicht übersprungen und die Thread-Erstellung schlägt fehl. (Dies ist ein Fehler, der vor 6 Jahren mit einem Pull Request zur Behebung gemeldet wurde, der es nie in die Codebasis geschafft hat).

Außerdem gibt es in diesem Fall, im Gegensatz zum direkten Schreiben in die Datenbank, keine Unterstützung für Transaktionen, um die Erstellung des ursprünglichen Threads rückgängig zu machen, und Sie müssen ihn manuell finden, um ihn zu bereinigen und zu reparieren.

Vorerst scheint das Einfügen der Beiträge/Themen in Ordnung zu sein. Ich war etwas besorgt wegen der Spalte ‘cooked’, da diese nicht null sein konnte, aber ich fülle sie vorerst mit demselben Text wie ‘raw’ und lasse ‘baked_at’ und ‘baked_version’ NULL.

Bei der Ansicht scheint der Back-Prozess ausgelöst zu werden, sobald der Beitrag angezeigt wird.

OK. Ich habe einen Weg gefunden, das erneute Backen auszulösen:

rake posts:rebake

Verwenden Sie Spezifikationen und Import-Skripte als Leitfaden, um Discourse-Datenstrukturen über Ruby-Befehle zu manipulieren.

Verwenden Sie die Rails-Konsole für Experimente.

3 „Gefällt mir“

Es ist erwähnenswert, dass Sie, wenn Ihr Client in Ruby geschrieben ist, das Ruby API Gem verwenden können:

1 „Gefällt mir“

Wenn Sie den Datensatz mit Rails erstellen, wird das erneute Backen automatisch durchgeführt, wenn der Beitrag gespeichert wird, und es werden Benachrichtigungen und eine Reihe anderer Dinge gesendet.

Wenn der Beitrag mit direktem Datenbankzugriff erstellt wird, scheint Discourse ihn auch sofort neu zu backen.

1 „Gefällt mir“