Ciao, questo argomento fornisce un po’ di contesto sulla migrazione che sto lentamente pianificando e testando. Venerdì scorso ho finalmente provato l’importatore Drupal su un VPS di prova, utilizzando una combinazione di questo e questo. L’importatore è ancora in esecuzione mentre scrivo, quindi non sono ancora stato in grado di testare effettivamente la funzionalità del sito di prova, ma sta per finire.
Il problema più grande che sto affrontando è un “valore di chiave duplicato” su 8 nodi apparentemente casuali (l’equivalente degli argomenti in Discourse) su circa 80.000 nodi totali. Questi sono i numeri nid specifici nel caso in cui ci sia un bug matematico strano tipo Y2K:
42081, 53125, 57807, 63932, 66756, 76561, 78250, 82707
Questo stesso errore si verifica sempre sugli stessi nid quando si riesegue l’importatore:
Traceback (most recent call last):
19: from script/import_scripts/drupal.rb:537:in `<main>'
18: from /var/www/discourse/script/import_scripts/base.rb:47:in `perform'
17: from script/import_scripts/drupal.rb:39:in `execute'
16: from script/import_scripts/drupal.rb:169:in `import_forum_topics'
15: from /var/www/discourse/script/import_scripts/base.rb:916:in `batches'
14: from /var/www/discourse/script/import_scripts/base.rb:916:in `loop'
13: from /var/www/discourse/script/import_scripts/base.rb:917:in `block in batches'
12: from script/import_scripts/drupal.rb:195:in `block in import_forum_topics'
11: from /var/www/discourse/script/import_scripts/base.rb:224:in `all_records_exist?'
10: from /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/activerecord-7.0.3.1/lib/active_record/transactions.rb:209:in `transaction'
9: from /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/activerecord-7.0.3.1/lib/active_record/connection_adapters/abstract/database_statements.rb:316:in `transaction'
8: from /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/activerecord-7.0.3.1/lib/active_record/connection_adapters/abstract/transaction.rb:317:in `within_new_transaction'
7: from /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/activesupport-7.0.3.1/lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `synchronize'
6: from /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/activesupport-7.0.3.1/lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `handle_interrupt'
5: from /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/activesupport-7.0.3.1/lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `block in synchronize'
4: from /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/activesupport-7.0.3.1/lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `handle_interrupt'
3: from /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/activerecord-7.0.3.1/lib/active_record/connection_adapters/abstract/transaction.rb:319:in `block in within_new_transaction'
2: from /var/www/discourse/script/import_scripts/base.rb:231:in `block in all_records_exist?'
1: from /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rack-mini-profiler-3.0.0/lib/patches/db/pg.rb:56:in `exec'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rack-mini-profiler-3.0.0/lib/patches/db/pg.rb:56:in `exec': ERROR: duplicate key value violates unique constraint "import_ids_pkey" (PG::UniqueViolation)
DETAIL: Key (val)=(nid:42081) already exists.
20: from script/import_scripts/drupal.rb:537:in `<main>'
19: from /var/www/discourse/script/import_scripts/base.rb:47:in `perform'
18: from script/import_scripts/drupal.rb:39:in `execute'
17: from script/import_scripts/drupal.rb:169:in `import_forum_topics'
16: from /var/www/discourse/script/import_scripts/base.rb:916:in `batches'
15: from /var/www/discourse/script/import_scripts/base.rb:916:in `loop'
14: from /var/www/discourse/script/import_scripts/base.rb:917:in `block in batches'
13: from script/import_scripts/drupal.rb:195:in `block in import_forum_topics'
12: from /var/www/discourse/script/import_scripts/base.rb:224:in `all_records_exist?'
11: from /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/activerecord-7.0.3.1/lib/active_record/transactions.rb:209:in `transaction'
10: from /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/activerecord-7.0.3.1/lib/active_record/connection_adapters/abstract/database_statements.rb:316:in `transaction'
9: from /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/activerecord-7.0.3.1/lib/active_record/connection_adapters/abstract/transaction.rb:317:in `within_new_transaction'
8: from /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/activesupport-7.0.3.1/lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `synchronize'
7: from /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/activesupport-7.0.3.1/lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `handle_interrupt'
6: from /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/activesupport-7.0.3.1/lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `block in synchronize'
5: from /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/activesupport-7.0.3.1/lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `handle_interrupt'
4: from /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/activerecord-7.0.3.1/lib/active_record/connection_adapters/abstract/transaction.rb:319:in `block in within_new_transaction'
3: from /var/www/discourse/script/import_scripts/base.rb:243:in `block in all_records_exist?'
2: from /var/www/discourse/script/import_scripts/base.rb:243:in `ensure in block in all_records_exist?'
1: from /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rack-mini-profiler-3.0.0/lib/patches/db/pg.rb:56:in `exec'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rack-mini-profiler-3.0.0/lib/patches/db/pg.rb:56:in `exec': ERROR: current transaction is aborted, commands ignored until end of transaction block (PG::InFailedSqlTransaction)
L’unico modo in cui sono riuscito a farlo procedere è stato modificando le condizioni SQL:
...
LEFT JOIN node_counter nc ON nc.nid = n.nid
WHERE n.type = 'forum'
AND n.status = 1
AND n.nid != 42081
AND n.nid != 53125
AND n.nid != 57807
AND n.nid != 63932
AND n.nid != 66756
AND n.nid != 76561
AND n.nid != 78250
AND n.nid != 82707
LIMIT #{BATCH_SIZE}
OFFSET #{offset};
...
Ho ispezionato il primo nodo fallito e i nodi nid precedenti e successivi da entrambi i lati nel database Drupal di origine, e non riesco a vedere nulla di sbagliato. Il nid è impostato come chiave primaria e ha AUTO_INCREMENT, e il sito Drupal originale funziona bene, quindi non ci possono essere problemi fondamentali con l’integrità del database di origine.
Oltre al bug di cui sopra, queste sono le limitazioni che sto riscontrando con lo script:
-
Permalink: Sembra che lo script di importazione creerà permalink per gli URL dei nodi precedenti
example.com/node/XXXXXXX. Ma devo anche mantenere i link a commenti specifici all’interno di quei nodi, che hanno il formato:example.com/comment/YYYYYYY#comment-YYYYYYY(YYYYYYYè lo stesso in entrambe le occorrenze). Lo schema URL di Drupal non include l’ID del nodo a cui è associato il commento, mentre Discourse lo fa (example.com/t/topic-keywords/XXXXXXX/YY), quindi sembra una complicazione importante. -
Limitazioni sui nomi utente: Drupal consente spazi nei nomi utente. Capisco che Discourse no, almeno non consente ai nuovi utenti di crearli in quel modo. Questo post suggerisce che lo script di importazione “convertirà” automaticamente i nomi utente problematici, ma non vedo alcun codice per questo inAggiornamento: In realtà sembra che Discourse abbia gestito questo automaticamente nel modo corretto./import_scripts/drupal.rb. -
Utenti bannati: Sembra che lo script importi tutti gli utenti, inclusi gli account bannati. Potrei probabilmente aggiungere una condizione abbastanza facilmente alla selezione SQL
WHERE status = 1per importare solo gli account utente attivi, ma non sono sicuro che ciò causerebbe problemi con la serializzazione dei record. Soprattutto, preferirei mantenere quei nomi di account precedentemente bannati con i loro indirizzi email associati permanentemente bloccati in modo che gli stessi utenti problematici non si registrino di nuovo su Discourse. -
Campi del profilo utente: Qualcuno sa se c’è del codice di esempio in uno degli altri importatori per importare campi di informazioni personali dai profili utente? Ho solo un campo del profilo (“Location”) che devo importare.
-
Avatar (non Gravatar): Sembra piuttosto strano che ci sia codice nell’importatore Drupal per importare Gravatar ma non per le immagini avatar dell’account locale, molto più comunemente utilizzate.
-
Messaggi privati: Quasi tutti i forum Drupal 7 utilizzeranno probabilmente il modulo di terze parti privatemsg (non esiste una funzionalità ufficiale di PM di Drupal). L’importatore non supporta l’importazione di PM. Nel mio caso, devo importarne circa 1,5 milioni.
Grazie in anticipo per il tuo aiuto e per aver reso disponibile lo script di importazione Drupal.




