Ah… eu nunca pensei em executar o importador mais de uma vez nos dados de produção. Muito obrigado por essa ideia.
Então, basicamente, eu faria um dump do banco de dados de produção do Drupal e executaria uma importação completa, o tempo que levasse, enquanto deixaria o fórum Drupal aberto ao público, depois colocaria o fórum Drupal em modo offline, faria outro dump do banco de dados, carregaria-o na instância MySQL do importador e executaria o script do importador novamente?
A única desvantagem que vejo aí é que qualquer edição de postagem do Drupal, exclusão de postagem ou alterações no perfil de usuário existente durante esse intervalo (vamos chamá-lo de 3 dias) da importação inicial até a segunda importação não seriam importadas, apenas novos usuários e postagens durante esse intervalo, correto?
Correto. Dados que forem editados serão perdidos. A alternativa é tirar o fórum do ar durante esse tempo. Você poderia avisar as pessoas. Na prática, ninguém reclamou.
Pouco depois de me comprometer com a execução final da importação de produção, estava verificando aleatoriamente alguns dos tópicos de fórum importados quando descobri um grande problema. Como tem sido o tema recorrente aqui, não é realmente culpa do Discourse ou do script de importação. Mas acontece que, quando uma resposta de tópico (“comentário” na linguagem do Drupal) é editada, ela às vezes altera o timestamp created. Pelo que pude apurar, deveria alterar o timestamp changed em vez disso. Mas, apesar desse bug no Drupal, ele ainda mantém a ordem de encadeamento dos comentários. No entanto, a forma como o script de importação do Drupal para o Discourse funciona, aparentemente, ordena as respostas por seu timestamp created (embora eu não veja nenhuma cláusula ORDER no script drupal.rb). Pelo meu teste no phpMyAdmin no banco de dados do Drupal, parece que ele simplesmente precisa de um ORDER BY c.cid ASC para manter a ordem correta de encadeamento através do ID original do comentário do Drupal cid, que é sequencial e nunca muda. Mas não tenho certeza se o importador do Discourse permitirá que respostas sequenciais tenham datas fora de ordem e/ou se ele fará sua própria ordenação por data de postagem? Gostaria de obter a opinião do criador original do importador drupal.rb (e de qualquer outra pessoa também, obviamente), isso funcionaria e haveria alguma consequência não intencional?
Eu acho (mas não sei ao certo, o banco de dados do drupal não faz sentido para mim) que você pode ajustar a consulta para obter o created at da postagem original e não da editada.
Eu acho que existe uma tabela que contém a postagem/hora original e outra com as edições.
Eu acho que ordenar por cid não vai prejudicar nada.
Não faz sentido nenhum. O problema é o seguinte: as duas linhas destacadas deveriam ser as 2ª e 3ª respostas na thread, mas no Discourse elas estão em alguma posição depois da 500ª porque é aí que está o timestamp delas.
E, claro, o Drupal decidiu definir created e changed para a mesma coisa… E isso só acontece às vezes, não consigo reproduzir editando postagens antigas. Mas tenho o mesmo problema em várias threads de longa duração onde o autor original do tópico postou e, em seguida, imediatamente postou um ou dois comentários de acompanhamento com “reservado” no corpo para adicionar informações posteriormente, o que ele fez vários anos depois.
Isso faria sentido, mas aqui está o mesmo comentário problemático editado espalhado pelas duas tabelas que ele usa:
OK, parece que isso funciona, corrige os dois tópicos confusos que encontrei e não parece prejudicar mais nada.
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 #<--- Corrigido
LIMIT #{BATCH_SIZE}
OFFSET #{offset}
SQL
).to_a
Hmm, parece que isso voltou para me morder. Como a função postprocess_posts substitui links internos antigos pelo novo URL do Discourse, eu fiz uma exceção no código para os links https://web.archive.org/web/20230101093741/https://MyOldForum.com/node/98765 que meu importador criou para as antigas enquetes do Drupal na Wayback Machine. Mas aparentemente algo deu errado, porque acabei de notar no site de migração em produção que os links acabaram como https://web.archive.org/web/20230101093741/https://MyOldForum.com/t/-/12345.
Então, agora que não estou mais no contexto de um contêiner de migração, o campo personalizado com o nid original do nó Drupal ainda está disponível na tabela de tópicos do Discourse? Se sim, pareceria possível fazer uma substituição de string no console Rails em todos os tópicos com a primeira postagem que contém View this poll on the Wayback Machine e, em seguida, substituir https://web.archive.org/web/20230101093741/https://MyOldForum.com/t/-/[01234567890]*
por https://web.archive.org/web/20230101093741/http://MyOldForum.com/node/$original_nid
Aqui está minha função original de importação de enquete:
def import_poll_topics
puts '', "importando tópicos de enquete"
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 ou então postprocess_posts() tentará converter o link Wayback Machine /node/YYY
raw: "### Ver esta enquete na 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