Oh… Je n’avais même jamais pensé à exécuter l’importateur plus d’une fois sur les données de production. Merci beaucoup pour cette idée.
Donc, en gros, je ferais un dump de la base de données Drupal de production et j’exécuterais une importation complète, peu importe le temps que cela prendrait, tout en laissant le forum Drupal ouvert au public, puis je mettrais le forum Drupal en mode hors ligne, je ferais un autre dump de la base de données, je le chargerais dans l’instance MySQL de l’importateur et je relancerais le script d’importation ?
Le seul inconvénient que je vois là-dedans est que toute modification de publication Drupal, toute suppression de publication ou tout changement de profil utilisateur existant pendant cet intervalle (appelons-le 3 jours) entre la première importation et la seconde importation ne serait pas importé, seuls les nouveaux utilisateurs et les nouvelles publications pendant cet intervalle seraient importés, c’est exact ?
C’est exact. Les données qui sont modifiées seront perdues. L’alternative est de mettre le forum hors ligne pendant ce temps. Vous pourriez prévenir les gens. En pratique, personne ne s’est plaint.
Juste après m’être engagé dans la dernière exécution d’importation de production, j’ai vérifié au hasard certains des fils de discussion importés lorsque j’ai découvert un problème majeur. Comme cela a été le thème récurrent ici, ce n’est pas vraiment la faute de Discourse ou du script d’importation. Mais il s’avère que lorsqu’une réponse à un sujet (« commentaire » dans le jargon de Drupal) est modifiée, elle modifie parfois l’horodatage created. Autant que je sache, elle devrait plutôt modifier l’horodatage changed. Mais malgré ce bug dans Drupal, il conserve toujours l’ordre des commentaires. Or, la façon dont le script d’importation Drupal pour Discourse fonctionne, il trie apparemment les réponses par leur horodatage created (bien que je ne voie aucune clause ORDER dans le script drupal.rb). D’après mes tests dans phpMyAdmin sur la base de données Drupal, il semble qu’il suffise d’ajouter un ORDER BY c.cid ASC pour maintenir le bon ordre des commentaires via l’ID de commentaire d’origine de Drupal cid qui est séquentiel et ne change jamais. Mais je ne suis pas sûr si l’importateur Discourse autorisera des réponses séquentielles avec des dates désordonnées, et/ou s’il procédera à son propre tri par date de publication ? J’aimerais avoir l’avis du créateur original de l’importateur drupal.rb (et de toute autre personne aussi, évidemment), est-ce que cela fonctionnerait et y aurait-il des conséquences imprévues ?
Je pense (mais je ne sais pas vraiment, la base de données de Drupal n’a aucun sens pour moi) que vous pouvez ajuster la requête pour récupérer la date de création de la publication originale et non celle de la publication modifiée.
Je pense qu’il existe une table qui contient la publication/l’heure originale et une autre avec les modifications.
Je pense que le tri par cid ne fera de mal à rien.
Cela n’a vraiment aucun sens. Le problème est le suivant : les deux lignes mises en surbrillance devraient être la 2e et la 3e réponse dans le fil de discussion, mais dans Discourse, elles se trouvent quelque part après la 500e position car c’est là que se trouve leur horodatage.
Et bien sûr, Drupal a décidé de définir created et changed sur la même chose… Et cela n’arrive que parfois, je ne peux pas le reproduire moi-même en modifiant de vieilles publications. Mais j’ai le même problème dans plusieurs fils de discussion de longue date où l’auteur de la publication l’a publiée, puis a immédiatement publié un ou deux commentaires de suivi avec “réservé” dans le corps pour ajouter des informations plus tard, ce qu’il a fait plusieurs années plus tard.
Cela aurait du sens, mais voici le même commentaire problématique édité réparti sur les deux tables qu’il utilise :
OK, il semble que cela fonctionne, cela corrige les deux conversations mélangées que j’ai trouvées et ne semble rien d’autre affecter.
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 # <--- Corrigé
LIMIT #{BATCH_SIZE}
OFFSET #{offset}
SQL
).to_a
Hmm, il semble que cela me revienne. Puisque la fonction postprocess_posts remplace les anciens liens internes par la nouvelle URL Discourse, j’avais fait une exception dans le code pour les liens https://web.archive.org/web/20230101093741/https://MyOldForum.com/node/98765 que mon importateur avait créés pour les anciens sondages Drupal dans la Wayback Machine. Mais apparemment, quelque chose s’est mal passé, car je viens de remarquer sur le site migré en production que les liens se sont retrouvés comme https://web.archive.org/web/20230101093741/https://MyOldForum.com/t/-/12345.
Donc, maintenant que je ne suis plus dans le contexte d’un conteneur de migration, le champ personnalisé avec le nid d’origine du nœud Drupal est-il toujours disponible dans la table des sujets Discourse ? Si oui, il semblerait possible de faire un remplacement de chaîne dans la console Rails sur tous les sujets avec le premier message qui contient View this poll on the Wayback Machine et ensuite remplacer https://web.archive.org/web/20230101093741/https://MyOldForum.com/t/-/[01234567890]*
par https://web.archive.org/web/20230101093741/http://MyOldForum.com/node/$original_nid
Voici ma fonction d’importation de sondage d’origine :
def import_poll_topics
puts '', "importation des sujets de sondage"
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']),
# Utiliser TEMPmyoldforum.com ou sinon postprocess_posts() essaiera de convertir le lien Wayback Machine /node/YYY
raw: "### Voir ce sondage sur la 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