Oh… Ich habe nie darüber nachgedacht, den Importer mehr als einmal auf Produktionsdaten auszuführen. Vielen Dank für diese Idee.
Im Grunde würde ich also einen Produktions-Drupal-Datenbank-Dump erstellen und einen vollständigen Import durchführen, so lange das dauert, während das Drupal-Forum für die Öffentlichkeit geöffnet bleibt. Dann würde ich das Drupal-Forum in den Offline-Modus versetzen, einen weiteren Datenbank-Dump erstellen, diesen in die Importer-MySQL-Instanz laden und das Importer-Skript erneut ausführen?
Der einzige Nachteil, den ich hier sehe, ist, dass alle Drupal-Beitragsbearbeitungen oder Beitrags_löschungen_ oder Änderungen am bestehenden Benutzerprofil während dieses Zeitraums (nennen wir ihn 3 Tage) vom ursprünglichen Import bis zum zweiten Import nicht importiert würden, sondern nur vollständig neue Benutzer und Beiträge während dieses Zeitraums, richtig?
Das stimmt. Daten, die bearbeitet werden, gehen verloren. Die Alternative ist, das Forum für diese Zeit offline zu nehmen. Sie könnten die Leute warnen. In der Praxis hat sich niemand beschwert.
Kurz nachdem ich mich für den endgültigen Produktionsimportlauf entschieden hatte, überprüfte ich zufällig einige der importierten Foren-Threads, als ich ein großes Problem entdeckte. Wie schon so oft, ist es nicht wirklich die Schuld von Discourse oder dem Importskript. Aber es stellt sich heraus, dass, wenn eine Themenantwort („Kommentar“ im Drupal-Jargon) bearbeitet wird, sich manchmal der created-Zeitstempel ändert. Soweit ich das beurteilen kann, sollte stattdessen der changed-Zeitstempel geändert werden. Aber trotz dieses Fehlers in Drupal bleibt die Kommentar-Thread-Reihenfolge erhalten. Die Art und Weise, wie das Drupal-Importskript für Discourse funktioniert, sortiert die Antworten anscheinend nach ihrem created-Zeitstempel (obwohl ich keine ORDER-Klauseln im drupal.rb-Skript sehe). Aus meinen Tests in phpMyAdmin auf der Drupal-Datenbank sieht es so aus, als ob einfach ein ORDER BY c.cid ASC benötigt wird, um die korrekte Thread-Reihenfolge über die ursprüngliche Drupal-Kommentar-ID cid aufrechtzuerhalten, die sequenziell ist und sich nie ändert. Aber ich bin mir nicht sicher, ob der Discourse-Importeur zulässt, dass sequenzielle Antworten Daten haben, die nicht in der richtigen Reihenfolge sind, und/oder ob er seine eigene Sortierung nach Datum vornimmt? Ich hätte gerne die Meinung des ursprünglichen Erstellers des drupal.rb-Importeurs (und natürlich auch von jedem anderen), würde das funktionieren und gäbe es unbeabsichtigte Folgen?
Ich glaube (aber ich weiß es nicht wirklich, DrupaLs Datenbank ergibt für mich keinen Sinn), dass Sie die Abfrage so anpassen können, dass das Erstellungsdatum des Originalbeitrags und nicht des bearbeiteten Beitrags abgerufen wird.
Ich glaube, es gibt eine Tabelle, die den Originalbeitrag/die Originalzeit enthält, und eine weitere mit den Bearbeitungen.
Ich glaube, dass die Sortierung nach cid nichts schaden wird.
Es ergibt wirklich keinen Sinn. Das Problem ist wie folgt: Die beiden hervorgehobenen Zeilen sollten die 2. und 3. Antwort im Thread sein, aber in Discourse befinden sie sich irgendwo nach der 500. Position, da dort ihr Zeitstempel liegt.
Und natürlich hat Drupal beschlossen, created und changed auf dasselbe zu setzen… Und es passiert nur manchmal, ich kann es nicht reproduzieren, indem ich alte Beiträge bearbeite. Aber ich habe dasselbe Problem in mehreren langlaufenden Threads, bei denen der OP des Themas es gepostet und dann sofort ein oder zwei Folgekommentare mit „reserviert“ im Text gepostet hat, um später zusätzliche Informationen hinzuzufügen, was er mehrere Jahre später tat.
Das wäre sinnvoll, aber hier ist derselbe problematische bearbeitete Kommentar, verteilt auf die beiden Tabellen, die er verwendet:
OK, es sieht so aus, als ob dies funktioniert, es behebt die beiden durcheinandergeratenen Threads, die ich gefunden habe, und scheint nichts anderes zu beeinträchtigen.
def import_replies
…
batches(BATCH_SIZE) do |offset|
results = mysql_query(<<-SQL
SELECT c.cid, c.pid, c.nid, c.uid, c.created,
f.comment_body_value body,
f.comment_body_format format
FROM comment c,
field_data_comment_body f,
node n
WHERE c.cid = f.entity_id
AND n.nid = c.nid
AND c.status = 1
AND n.type IN ('poll', 'forum')
AND n.status = 1
AND c.created > UNIX_TIMESTAMP(STR_TO_DATE('#{IMPORT_AFTER}', '%Y-%m-%d'))
ORDER BY c.cid ASC #<--- Fixed
LIMIT #{BATCH_SIZE}
OFFSET #{offset}
SQL
).to_a
Hm, das scheint mir auf die Füße gefallen zu sein. Da die Funktion postprocess_posts alte interne Links durch die neue Discourse-URL ersetzt, hatte ich im Code eine Ausnahme für die Links https://web.archive.org/web/20230101093741/https://MyOldForum.com/node/98765 gemacht, die mein Importer für die alten Drupal-Umfragen im Wayback Machine erstellt hat. Aber anscheinend ist etwas schief gelaufen, denn ich habe gerade auf der produktiven migrierten Website festgestellt, dass die Links wie https://web.archive.org/web/20230101093741/https://MyOldForum.com/t/-/12345 aussehen.
Da ich mich nicht mehr im Kontext eines Migrationscontainers befinde, ist das benutzerdefinierte Feld mit der ursprünglichen Drupal-Knoten-nid noch in der Discourse-Themen-DB-Tabelle verfügbar? Wenn ja, wäre es möglich, in der Rails-Konsole eine Zeichenfolgenersetzung für alle Themen mit dem ersten Beitrag durchzuführen, der View this poll on the Wayback Machine enthält, und dann zu ersetzen: https://web.archive.org/web/20230101093741/https://MyOldForum.com/t/[01234567890]*
mit https://web.archive.org/web/20230101093741/http://MyOldForum.com/node/$original_nid
Hier ist meine ursprüngliche Umfrage-Importfunktion:
def import_poll_topics
puts '', "importing poll topics"
polls = mysql_query(<<-SQL
SELECT n.nid nid, n.title title, n.uid uid, n.created created, n.sticky sticky, taxonomy_index.tid tid, node_counter.totalcount views
FROM node n
LEFT JOIN taxonomy_index ON n.nid = taxonomy_index.nid
LEFT JOIN node_counter ON n.nid = node_counter.nid
WHERE n.type = 'poll'
AND n.status = 1
SQL
).to_a
create_posts(polls) do |topic|
{
id: "nid:#{topic['nid']}",
user_id: user_id_from_imported_user_id(topic['uid']) || -1,
category: category_id_from_imported_category_id(topic['tid']),
# Use TEMPmyoldforum.com or else postprocess_posts() will try to convert the Wayback Machine /node/YYY link
raw: "### View this poll on the Wayback Machine:\n**https://web.archive.org/web/20230101093741/http://TEMPmyoldforum.com/node/#{topic['nid']}**",
created_at: Time.zone.at(topic['created']),
pinned_at: topic['sticky'].to_i == 1 ? Time.zone.at(topic['created']) : nil,
title: topic['title'].try(:strip),
views: topic['views'],
custom_fields: { import_id: "nid:#{topic['nid']}" }
}
end
end