فكرتُ فقط في أن أنشر منشورًا سريعًا يشرح بإيجاز كيف قمتُ بنقل منتدى يضم أكثر من 25,000 عضو وأكثر من 250,000 منشور من Flarum إلى Discourse.
وكما هو معلوم لمن يقرأ هذا، لا توجد سكريبت استيراد رسمي للانتقال من Flarum إلى Discourse. ومع ذلك، ساهم الزميل @koen360 بلطف بمشاركته لعمله في تعديل أداة استيراد FluxBB لاستيراد المستخدمين. لكننا احتجنا أيضًا إلى استيراد المنشورات، لأن جزءًا كبيرًا من نجاح منتدانا يعتمد على قدرة المستخدمين على البحث عن مصطلحات محددة جدًا تظهر داخل المنشورات. وهذا ما فعلناه… بعد عدة ساعات من محاولات النقل الفاشلة، وصداع، وبعض الجروح.
أنا لست خبيرًا في كتابة سكريبتات النقل، لكن هذا السكريبت يعمل بشكل جيد بما يكفي للإصدار الحالي من Flarum وقت كتابة هذا النص (V0.1.0-beta.16). سيتطلب السكريبت (المرفق أدناه) الوصول إلى قاعدة بيانات MySQL/MariaDB الخاصة بكم، ويفضل أن تكون نسخة منها حتى لا تتسبب في أضرار لموقع الإنتاج في حال حدوث أي خطأ. فقط استبدل القيم الوهمية في اتصال MySQL وستكون جاهزًا.
تأكد فقط من أن لديك نسخة احتياطية كاملة من قاعدة بيانات Flarum قبل البدء في هذه العملية، لأنه في حال حدوث أي خطأ قد يكون من المستحيل عكسه.
إذا كنت بحاجة إلى مساعدة في عملية النقل من Flarum إلى Discourse، فلا تتردد في الرد على هذا الموضوع. أنا لست خبيرًا، لكنني سأبذل قصارى جهدي للمساعدة قدر الإمكان.
شكرًا لك على كتابة السكربت @Lecter! هل يمكنك تقديمه كـ PR إلى discourse/discourse؟ لا نملك سكريبت Flarum بعد، لذا سيكون من المفيد أن يكون هذا كنقطة انطلاق.
هذا رائع، شكرًا لك على دفع هذا المصدّر خطوة إلى الأمام! آمل حقًا أن يتم توسيعه في المستقبل ليشمل الوسوم (Tags)، إن لم يكن المرفقات.
كم من الجهد قد يتطلب إضافة دعم الوسوم؟ أرى أن vBulletin 5 وربما بضع منصات أخرى لديها نماذج محتملة توضح كيفية عملها، لكنني لا أعرف مدى الحاجة إلى تعديل ذلك ليتوافق مع Flarum. شكرًا على أي توضيح يمكن لأي شخص تقديمه، ولا تقلقوا إذا لم يكن بالإمكان الإجابة على هذا السؤال إلا من خلال تنفيذه فعليًا.
لدي Discourse مع مشاركات فارغة و 3 فئات افتراضية.
عندما حاولت استيراد SQL من Flarum إلى Discourse، واجهت هذا الخطأ
su discourse -c 'bundle exec ruby script/import_scripts/flarum_import.rb'
Loading existing groups...
Loading existing users...
Loading existing categories...
Loading existing posts...
Loading existing topics...
creating users
13 / 13 (100.0%) [281 items/min] n]
importing top level categories...
39 / 39 (100.0%) [420 items/min] n]
importing children categories...
39 / 39 (100.0%) [290 items/min]
creating topics and posts
Traceback (most recent call last):
19: from script/import_scripts/flarum_import.rb:162:in `<main>'
18: from /var/www/discourse/script/import_scripts/base.rb:47:in `perform'
17: from script/import_scripts/flarum_import.rb:32:in `execute'
16: from script/import_scripts/flarum_import.rb:101:in `import_posts'
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/flarum_import.rb:122:in `block in import_posts'
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/lib/active_record/transactions.rb:209:in `transaction'
9: from /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/activerecord-7.0.3/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/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/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/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/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/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/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)=(7) already exists.
20: from script/import_scripts/flarum_import.rb:162:in `<main>'
19: from /var/www/discourse/script/import_scripts/base.rb:47:in `perform'
18: from script/import_scripts/flarum_import.rb:32:in `execute'
17: from script/import_scripts/flarum_import.rb:101:in `import_posts'
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/flarum_import.rb:122:in `block in import_posts'
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/lib/active_record/transactions.rb:209:in `transaction'
10: from /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/activerecord-7.0.3/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/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/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/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/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/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/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)
root@raspberrypi-app:/var/www/discourse# rake db:validate_indexes
Starting postgres on port: 11000
Waiting for PG server to start...
PG server is ready and DB is loaded
Running migrations on blank database!
Testing indexes on the default database
No missing indexes
No extra indexes
ubuntu@ip-172-26-1-78:~/discourse$ bundle exec ruby script/import_scripts/flarum_import.rb
Loading existing groups...
Loading existing users...
Loading existing categories...
Loading existing posts...
Loading existing topics...
creating users
Skipping 1000 already imported users
Skipping 826 already imported users
importing top level categories...
34 / 34 (100.0%) [5728165 items/min]
importing children categories...
34 / 34 (100.0%) [3194 items/min]
creating topics and posts
Traceback (most recent call last):
19: from script/import_scripts/flarum_import.rb:162:in `<main>'
18: from /home/ubuntu/discourse/script/import_scripts/base.rb:47:in `perform'
17: from script/import_scripts/flarum_import.rb:32:in `execute'
16: from script/import_scripts/flarum_import.rb:101:in `import_posts'
15: from /home/ubuntu/discourse/script/import_scripts/base.rb:916:in `batches'
14: from /home/ubuntu/discourse/script/import_scripts/base.rb:916:in `loop'
13: from /home/ubuntu/discourse/script/import_scripts/base.rb:917:in `block in batches'
12: from script/import_scripts/flarum_import.rb:122:in `block in import_posts'
11: from /home/ubuntu/discourse/script/import_scripts/base.rb:224:in `all_records_exist?'
10: from /home/ubuntu/.rbenv/versions/2.7.6/lib/ruby/gems/2.7.0/gems/activerecord-7.0.3.1/lib/active_record/transactions.rb:209:in `transaction'
9: from /home/ubuntu/.rbenv/versions/2.7.6/lib/ruby/gems/2.7.0/gems/activerecord-7.0.3.1/lib/active_record/connection_adapters/abstract/database_statements.rb:316:in `transaction'
8: from /home/ubuntu/.rbenv/versions/2.7.6/lib/ruby/gems/2.7.0/gems/activerecord-7.0.3.1/lib/active_record/connection_adapters/abstract/transaction.rb:317:in `within_new_transaction'
7: from /home/ubuntu/.rbenv/versions/2.7.6/lib/ruby/gems/2.7.0/gems/activesupport-7.0.3.1/lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `synchronize'
6: from /home/ubuntu/.rbenv/versions/2.7.6/lib/ruby/gems/2.7.0/gems/activesupport-7.0.3.1/lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `handle_interrupt'
5: from /home/ubuntu/.rbenv/versions/2.7.6/lib/ruby/gems/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 /home/ubuntu/.rbenv/versions/2.7.6/lib/ruby/gems/2.7.0/gems/activesupport-7.0.3.1/lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `handle_interrupt'
3: from /home/ubuntu/.rbenv/versions/2.7.6/lib/ruby/gems/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 /home/ubuntu/discourse/script/import_scripts/base.rb:243:in `block in all_records_exist?'
1: from /home/ubuntu/discourse/script/import_scripts/base.rb:243:in `ensure in block in all_records_exist?'
1: from /home/ubuntu/.rbenv/versions/2.7.6/lib/ruby/gems/2.7.0/gems/rack-mini-profiler-3.0.0/lib/patches/db/pg.rb:56:in `exec'
/home/ubuntu/.rbenv/versions/2.7.6/lib/ruby/gems/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)=(53) already exists.
20: from script/import_scripts/flarum_import.rb:162:in `<main>'
19: from /home/ubuntu/discourse/script/import_scripts/base.rb:47:in `perform'
18: from script/import_scripts/flarum_import.rb:32:in `execute'
17: from script/import_scripts/flarum_import.rb:101:in `import_posts'
16: from /home/ubuntu/discourse/script/import_scripts/base.rb:916:in `batches'
15: from /home/ubuntu/discourse/script/import_scripts/base.rb:916:in `loop'
14: from /home/ubuntu/discourse/script/import_scripts/base.rb:917:in `block in batches'
13: from script/import_scripts/flarum_import.rb:122:in `block in import_posts'
12: from /home/ubuntu/discourse/script/import_scripts/base.rb:224:in `all_records_exist?'
11: from /home/ubuntu/.rbenv/versions/2.7.6/lib/ruby/gems/2.7.0/gems/activerecord-7.0.3.1/lib/active_record/transactions.rb:209:in `transaction'
10: from /home/ubuntu/.rbenv/versions/2.7.6/lib/ruby/gems/2.7.0/gems/activerecord-7.0.3.1/lib/active_record/connection_adapters/abstract/database_statements.rb:316:in `transaction'
9: from /home/ubuntu/.rbenv/versions/2.7.6/lib/ruby/gems/2.7.0/gems/activerecord-7.0.3.1/lib/active_record/connection_adapters/abstract/transaction.rb:317:in `within_new_transaction'
8: from /home/ubuntu/.rbenv/versions/2.7.6/lib/ruby/gems/2.7.0/gems/activesupport-7.0.3.1/lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `synchronize'
7: from /home/ubuntu/.rbenv/versions/2.7.6/lib/ruby/gems/2.7.0/gems/activesupport-7.0.3.1/lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `handle_interrupt'
6: from /home/ubuntu/.rbenv/versions/2.7.6/lib/ruby/gems/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 /home/ubuntu/.rbenv/versions/2.7.6/lib/ruby/gems/2.7.0/gems/activesupport-7.0.3.1/lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `handle_interrupt'
4: from /home/ubuntu/.rbenv/versions/2.7.6/lib/ruby/gems/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 /home/ubuntu/discourse/script/import_scripts/base.rb:243:in `block in all_records_exist?'
2: from /home/ubuntu/discourse/script/import_scripts/base.rb:243:in `ensure in block in all_records_exist?'
1: from /home/ubuntu/.rbenv/versions/2.7.6/lib/ruby/gems/2.7.0/gems/rack-mini-profiler-3.0.0/lib/patches/db/pg.rb:56:in `exec'
/home/ubuntu/.rbenv/versions/2.7.6/lib/ruby/gems/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)