ترحيل قاعدة بيانات vBulletin 5 - أخطاء في سكربت الاستيراد

نعم، سأفعل ذلك إذا تمكنت من إكمال استيراد المستخدم على الأقل. حاليًا، يتعطل عند محاولة العمل على رسائل البريد الإلكتروني

فقط قم بإزالة السطر الأول من البرنامج النصي script/bulk_import/vbulletin5.rb
# frozen_string_literal: true

إعجابَين (2)

حسنًا، عند تشغيل الدوال الثلاث الأولى فقط:

 def execute
    # enable as per requirement:
    #SiteSetting.automatic_backups_enabled = false
    #SiteSetting.disable_emails = "non-staff"
    #SiteSetting.authorized_extensions = '*'
    #SiteSetting.max_image_size_kb = 102400
    #SiteSetting.max_attachment_size_kb = 102400
    #SiteSetting.clean_up_uploads = false
    #SiteSetting.clean_orphan_uploads_grace_period_hours = 43200
    #SiteSetting.max_category_nesting = 3

    import_groups
    import_users
    import_group_users

    #import_user_emails
    #import_user_stats
    #import_user_profiles
    #import_user_account_id

    #import_categories
    #import_topics
    #import_topic_first_posts
    #import_replies

    #import_likes

    #import_private_topics
    #import_topic_allowed_users
    #import_private_first_posts
    #import_private_replies

    #create_oauth_records
    #create_permalinks
    #import_attachments
  end

النتيجة:

أفترض أن هذه الرسالة حول ضمان الاتساق مخصصة عند اكتمال الاستيراد الكامل؟ أم يجب علي تشغيلها في كل “خطوة” أقوم بتشغيلها ثم أخذ نسخة من دليل discourse من المضيف للحصول على نسخة احتياطية؟

إعجاب واحد (1)

إعادة تشغيله مع تفعيل الوظائف الأربع التالية يُرجع خطأ لمعرفات موجودة بالفعل

هل يمكن أن يكون هذا “الكل أو لا شيء”؟ ربما يتوقع أن يتم كل شيء في معاملة واحدة كبيرة؟

تمت المحاولة مرة أخرى. مرت العملية لفترة طويلة ثم فجأة حدث هذا.

الجزء المحبط هو أنه يبدو أنه حدث من فراغ.
الآن يؤدي تشغيله مرة أخرى إلى هذا الخطأ.

متعب جدًا الآن للتحقق مما يشير إليه. خاصة لأن duplicate key value لا ينبغي أن يحدث على الإطلاق إذا قمت ببساطة بإعادة تشغيل البرنامج النصي للاستيراد المجمع، أليس كذلك؟

أود أن أبدأ بالاعتذار لأي شخص قد يشعر بالهجوم بسبب هذا المنشور، لأنه بصراحة، منذ يوم الاثنين وأنا أتعامل مع هذه المشاكل، وفي هذه المرحلة أنا متعب من تصحيح الأخطاء / الإصلاحات السريعة لكود Discourse.

بعد المحاولة الـ nth (توقفت عن العد بعد السابعة) أعتقد أنني سأستسلم لأنه يبدو أن الترحيل ليس شيئًا استثمر فيه Discourse الكثير من الوقت لدعمه.

أعتقد أن المشكلة الأكبر هي أن مجموعة الأحرف المستخدمة في قاعدة البيانات الضخمة هذه هي utf8mb4 والتي لا يدعمها البرنامج النصي (؟).

استخدام utf8 (الافتراضي) يولد الكثير من الأخطاء التي يتم الإبلاغ عنها ولكن ليس من الواضح ما يحدث حيث يستمر البرنامج النصي على أي حال. هل يتم تخطي الإدخال في قاعدة البيانات؟ هل يتم نسخه مع بعض الأحرف غير المدعومة (المربعات الكلاسيكية)؟

علاوة على ذلك، فإن آخر ثلاثة تشغيلات مختلفة (باستخدام مستوردي الدُفعات)، مع اتباع نفس مجموعة التعليمات بالضبط، لها نتائج مختلفة. وصل هذا التشغيل الأخير إلى استيراد الموضوع، وبدأ على الفور في الإبلاغ عن أخطاء ولكنه استمر (؟؟؟):

تحميل التطبيق...
بدء...
تحميل مسبق لـ I18n...
إصلاح أعلى أرقام المشاركات...
تحميل معرفات المجموعات المستوردة...
تحميل معرفات المستخدمين المستوردة...
تحميل معرفات الفئات المستوردة...
تحميل معرفات المواضيع المستوردة...
تحميل معرفات المشاركات المستوردة...
تحميل فهارس المجموعات...
تحميل فهارس المستخدمين...
تحميل فهارس الفئات...
تحميل فهارس المواضيع...
تحميل فهارس المشاركات...
تحميل فهارس إجراءات المشاركات...
استيراد الفئات...
استيراد الفئات الأصلية...
      5 -   1104/ثانية
استيراد الفئات الفرعية...
    500 -   1539/ثانيةخطأ: قيمة مفتاح مكررة تنتهك قيد التفرد "unique_index_categories_on_name"
التفاصيل: المفتاح (COALESCE(parent_category_id, '-1'::integer), name)=(-1, Armata Brancaleone) موجود بالفعل.
السياق: COPY categories, line 69
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/pg-1.4.5/lib/pg/connection.rb:204:in `get_last_result'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/pg-1.4.5/lib/pg/connection.rb:204:in `copy_data'
/var/www/discourse/script/bulk_import/base.rb:720:in `create_records'
/var/www/discourse/script/bulk_import/base.rb:361:in `create_categories'
script/bulk_import/vbulletin5.rb:291:in `import_categories'
script/bulk_import/vbulletin5.rb:69:in `execute'
/var/www/discourse/script/bulk_import/base.rb:98:in `run'
script/bulk_import/vbulletin5.rb:779:in `<main>'
استيراد المواضيع...
    600 -   4073/ثانية
خطأ: طريقة غير معرفة `[]' لـ nil:NilClass
/var/www/discourse/script/bulk_import/base.rb:513:in `process_topic'
/var/www/discourse/script/bulk_import/base.rb:724:in `block (2 levels) in create_records'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rack-mini-profiler-3.0.0/lib/patches/db/mysql2/alias_method.rb:8:in `each'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rack-mini-profiler-3.0.0/lib/patches/db/mysql2/alias_method.rb:8:in `each'
/var/www/discourse/script/bulk_import/base.rb:721:in `block in create_records'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/pg-1.4.5/lib/pg/connection.rb:196:in `copy_data'
/var/www/discourse/script/bulk_import/base.rb:720:in `create_records'
/var/www/discourse/script/bulk_import/base.rb:364:in `create_topics'
script/bulk_import/vbulletin5.rb:321:in `import_topics'
script/bulk_import/vbulletin5.rb:70:in `execute'
/var/www/discourse/script/bulk_import/base.rb:98:in `run'
script/bulk_import/vbulletin5.rb:779:in `<main>'

حتى يتعطل أخيرًا بسبب هذا:

script/bulk_import/vbulletin5.rb:779:in `<main>'
 572329 -    531/ثانية
استيراد الردود...
client_loop: send disconnect: Connection reset

ولكن ليس قبل أن يقوم بشكل أساسي بإزعاج هذين الخطأين باستمرار:

خطأ: طريقة غير معرفة `gsub!' لـ nil:NilClass
script/bulk_import/vbulletin5.rb:727:in `preprocess_raw'
script/bulk_import/vbulletin5.rb:369:in `block in import_topic_first_posts'
/var/www/discourse/script/bulk_import/base.rb:723:in `block (2 levels) in create_records'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rack-mini-profiler-3.0.0/lib/patches/db/mysql2/alias_method.rb:8:in `each'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rack-mini-profiler-3.0.0/lib/patches/db/mysql2/alias_method.rb:8:in `each'
/var/www/discourse/script/bulk_import/base.rb:721:in `block in create_records'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/pg-1.4.5/lib/pg/connection.rb:196:in `copy_data'
/var/www/discourse/script/bulk_import/base.rb:720:in `create_records'
/var/www/discourse/script/bulk_import/base.rb:367:in `create_posts'
script/bulk_import/vbulletin5.rb:361:in `import_topic_first_posts'
script/bulk_import/vbulletin5.rb:71:in `execute'
/var/www/discourse/script/bulk_import/base.rb:98:in `run'
script/bulk_import/vbulletin5.rb:779:in `<main>'

و

خطأ: تسلسل بايت غير صالح في UTF-8
script/bulk_import/vbulletin5.rb:727:in `gsub!'
script/bulk_import/vbulletin5.rb:727:in `preprocess_raw'
script/bulk_import/vbulletin5.rb:369:in `block in import_topic_first_posts'
/var/www/discourse/script/bulk_import/base.rb:723:in `block (2 levels) in create_records'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rack-mini-profiler-3.0.0/lib/patches/db/mysql2/alias_method.rb:8:in `each'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rack-mini-profiler-3.0.0/lib/patches/db/mysql2/alias_method.rb:8:in `each'
/var/www/discourse/script/bulk_import/base.rb:721:in `block in create_records'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/pg-1.4.5/lib/pg/connection.rb:196:in `copy_data'
/var/www/discourse/script/bulk_import/base.rb:720:in `create_records'
/var/www/discourse/script/bulk_import/base.rb:367:in `create_posts'
script/bulk_import/vbulletin5.rb:361:in `import_topic_first_posts'
script/bulk_import/vbulletin5.rb:71:in `execute'
/var/www/discourse/script/bulk_import/base.rb:98:in `run'
script/bulk_import/vbulletin5.rb:779:in `<main>'

يرجى ملاحظة أنني ذهبت خطوة بخطوة عن طريق التعليق على الوظيفة التي يجب تشغيلها، ثم تشغيل rake import:ensure_consistency قبل المتابعة عن طريق التعليق على الوظائف التي تم تشغيلها بالفعل وما إلى ذلك، لأنه إذا تركت البرنامج النصي بأكمله يعيد تشغيل الخطوات التي تم تشغيلها سابقًا، فإنه يتعطل ببساطة عن طريق العثور على معرفات مكررة.

قبل أن تأتي حجة “لا يمكنك الشكوى من البرامج المجانية” المعتادة، أريد أن أوضح أنني أساهم في مشاريع أخرى مفتوحة المصدر وأصنع برامج مجانًا أيضًا، ولكن من الضروري بالنسبة لي أنه إذا أصدرت شيئًا ما، فإن هذا الشيء يعمل ويوثق جيدًا (حتى لو فقط لتجنب الآلاف من الرسائل التي تسأل بشكل مبرر “كيف يعمل هذا”) أو أكون مستعدًا لإصلاح أي خطأ يظهر.

بينما يبدو أن Discourse يقدم تجربة رائعة جاهزة للاستخدام، يجب أن يكون واضحًا تمامًا أنه عام 2022 وأن المجتمعات كانت موجودة قبل هذا المنتج بوقت طويل. “التبني” سيحتاج إلى دعم ترحيل قوي ولا يبدو أن هذه هي الحالة الحالية لـ Discourse.

أدرك أن قاعدة بيانات بحجم 20 جيجابايت هي حالة استثنائية، لكننا لا نواجه مشكلة في الحجم هنا، بل في مجموعة الأحرف أو من يعرف ماذا، حيث لا يوجد حتى خطأ ثابت ومعظمها: لا توجد وثائق بخلاف البحث عن سلاسل الرسائل والمشاركات التي تركها من مروا بنفس المحنة في الماضي، على أمل العثور على حل بديل وأن الكود المصدري لم يتغير كثيرًا منذ ذلك الحين.

في هذه المرحلة، أوصي بشدة أي شخص قادم من vbulletin بتعليق أي ترحيل حتى يكتمل ما يبدو أنه إعادة هيكلة لبرنامج الترحيل (قيد الإنجاز على ما يبدو؟).

بينما أشعر بألمك (الترحيل موضوع صعب)، بصفتي متخصص ترحيل في Discourse، دعني أوضح الأمر.

لدينا إطار عمل ترحيل ناضج مع أكثر من 60 نصًا برمجيًا لمنصات مختلفة، وإطار عمل منفصل للترحيل بالجملة مع 5 نصوص برمجية، وإطار عمل أحدث قيد العمل والذي يحسن بشكل كبير كل جانب - الأداء، تنظيم الكود، قابلية الاختبار، قابلية التحقق، التوثيق، وما إلى ذلك.

لدينا فريق ترحيل منفصل مع دعم مطورين أساسيين واسع، ونساهم بتحسينات عامة في الكود مع كل ترحيل نكمله. نقوم باستمرار بإجراء عمليات ترحيل للعملاء تتراوح من البسيطة إلى المعقدة بشكل لا يصدق.

هدفنا النهائي هو جعل عمليات الترحيل سلسة قدر الإمكان لكل من العملاء المستضافين والمجتمع، ولكن كمية الكود التي تكون ضمن النطاق أثناء الترحيل ضخمة جدًا، وتكوين برامج النظام، وتغييرات البرامج الخارجية، وتنوع بيانات الإدخال يزيد المشكلة تعقيدًا.

مرة أخرى، أتمنى لو كانت كل هذه الأمور أقل إيلامًا، ولكن جعلها كذلك يتطلب ساعات عمل لا تحصى لإنشائها وصيانتها، وهناك عدد محدود فقط يمكن تخصيصه لذلك.

لا تستسلم! :slight_smile:

5 إعجابات

وأنا أقدر وأتفهم أن النطاق هائل. إنه أمر محبط الاستمرار في التعثر في استثناء تلو الآخر وحقيقة أن المشروع مكتوب بلغة روبي لا يساعد في العثور على مساعدة بخلاف القدوم إلى هنا بشكل أساسي، وهو ما لا يمكنه على الإطلاق استيعاب جميع طلبات المساعدة، كما تقول، بعض الحالات متخصصة للغاية ومن المستحيل المساعدة فيها إلا إذا كان لديك وصول إلى البيانات الفعلية.

أنا أيضًا، إلى حد كبير، ألقي باللوم على الفوضى المطلقة التي هي بنية vbulletin.

لقد تحققت هذا الصباح وهذا ملخص لأحجام الجداول.

لإعطاء سياق، فإن جدول “text” هو المكان الذي يوجد فيه المحتوى الفعلي.
يحتوي جدول node على التسلسل الهرمي و closure… دعني أقتبس هنا لأنني لا أستطيع حتى:

يبني جدول الإغلاق العلاقات بين الوالدين والطفل بين جميع العقد. غالبية قاعدة بياناتك تتكون من ملفات مرفقة لا ينبغي تخزينها في قاعدة البيانات على أي حال.

لذلك بشكل عام، بالنسبة لمنتدى يحتوي على حوالي 8 جيجابايت من المحتوى، هناك حمل إضافي قدره 28 جيجابايت. أشياء رائعة، تهانينا vbulletin.

إعجابَين (2)

هذا ما أعنيه عندما أقول إن الأمر محبط.

مرة أخرى، نفس مجموعة الإجراءات (اتباع دليل تشغيل كتبته بنفسي مع كل التجارب والأخطاء)، يتم تشغيله على تثبيت جديد لـ discourse.

النتيجة:

Tired Tv Land GIF by TV Land Classic

أين أنت import_user_account_id؟ :expressionless:
ولكن الأهم من ذلك؟ كيف تمكنت من عدم التسبب في خطأ في التشغيل السابق حيث فشل في استيراد الموضوع؟ :confounded:

تعليق استدعاء هذه الوظيفة (التي تبدو مهمة على أي حال) وتشغيلها مرة أخرى:

تلك الأخطاء المفاتيح المكررة… ألا يجب أن يعرف البرنامج النصي أنه قد قام بالفعل بتلك المعرفات وينتقل؟

كل استيراد مختلف. قد تعتقد أن برنامجًا نصيًا يعمل مع نسخة واحدة من منتدىك المفضل سابقًا سيعمل ببساطة، ولكنه لا يعمل. وبالنسبة لمنتدى ضخم، فإنه أمر صعب حقًا. إنه ببساطة ليس شيئًا يسهل دعمه. وتصل أدوات الاستيراد المجمعة مباشرة إلى قاعدة البيانات بدلاً من الاعتماد على Rails لتتمكن من التحقق تلقائيًا من الأشياء أثناء تقدمها.

هذه مشكلة شائعة، وليست خطأ البرنامج النصي. ستحتاج إلى معرفة كيفية نقل قاعدة بياناتك القديمة إلى utf8.

هناك دعم ترحيل قوي. لا يوجد دعم ترحيل مجاني. لقد قمت بحوالي 100 عملية ترحيل وكتبت العديد من نصوص الاستيراد للأنظمة غير المدعومة أو المخصصة. ربما سأتقاضى 3000-5000 دولار لاستيراد قاعدة بياناتك. هذا ليس عرضًا، بل هو فقط لإعطائك فكرة عن مقدار العمل الذي يتطلبه شخص قام بذلك عدة مرات. أشك في أنه إذا دفعت مقابل عام واحد من الاستضافة التجارية، فإن CDCK ستقوم بذلك مجانًا، وقد يكون ذلك أقل مما سأتقاضاه للقيام بذلك. (آه، ولكن قد لا تكون مؤهلاً للاستضافة التجارية بقاعدة بيانات بهذا الحجم).

إعجاب واحد (1)

متابعة استكشافي هنا.

  • يشير البرنامج النصي إلى دالة غير موجودة: import_user_account_id. قد ترغبون (مطوروا discourse) في إصلاح ذلك.
  • المنطق الذي يتحقق من عناوين المواضيع يجن جنونه بطريقة ما بسبب بعض المواضيع التي لسبب ما لها سلسلة فارغة كعنوان. بقدر ما لا ينبغي أن يحدث ذلك، فإن التحقق الذي يقيمه يجب أن يلتقطه ويعيد nil ولكن يبدو أن ذلك يكسر المنطق اللاحق المكتوب في الاستيراد (انظر هنا).

لقد واجهت هذه المشكلة مع بعض الاستيرادات التي قمت بها مؤخرًا. سيكون من الأفضل أن يعيد شيئًا مثل “الموضوع XXX مفقود عنوانه” أو يسحب السطر الأول من النص من المنشور، ولكن هذا صعب القيام به في هذا السياق. أعتقد أن ما سأكون أميل إلى فعله هو إصلاحه عن طريق تعديل قاعدة بياناتك واستخدام شيء آخر لإنشاء عناوين حيثما تكون مفقودة.

نعم، أنا في الأساس “أقوم بتنقية” قاعدة البيانات عندما أجد هذه المشكلات، لكن الأمر صعب حيث يتعين عليّ تصحيح الأخطاء في البرنامج النصي ثم تخمين سبب المشكلة في كل مرة :sweat_smile:

لا يزال ليس لدي أي فكرة عن الدالة المفقودة import_user_account_id :expressionless:

خاصة وأن العطلات قادمة قريبًا جدًا، فمن غير المرجح أن يقوم أي شخص بإصلاح ذلك ما لم يكن يستخدم البرنامج النصي بنفسه. (عادةً عندما أقول ذلك، يأتي ريتشارد وينقذ الموقف.)

إعجابَين (2)

LOL، حسنًا، أعتقد أنني سأخيب أملك اليوم. لقد حاولت، لكنني أشك في أن تثبيت هذا المستورد كان غير مكتمل ولم يتضمن بعض التغييرات على base.rb. لقد عمل @justin على هذا، ربما يعرف. أشك في أن هذا قد يكون شيئًا خاصًا بالعميل يمكن التعليق عليه دون عواقب أخرى.

لم أستخدم المستوردات المجمعة بنفسي أيضًا.

نعم، يمكن أن تكون نصوص الاستيراد معقدة وتعتمد على خصوصيات قاعدة البيانات، ولكن بعض النصوص ببساطة ليست في حالة عمل. وينطبق هذا على هذا النص أيضًا، وهناك بعض النصوص الأخرى التي تحتوي على # frozen_string_literal: true على سبيل المثال، والتي لا تعمل ببساطة خارج الصندوق.

إعجابَين (2)

ها!

هذا (على الأقل)

هو (على الأقل)

نعم. أعتقد أن شيئًا ما قد تم تنفيذه وأضاف frozen_string_literal إلى كل ملف. تم إصلاح معظم الملفات لأنها كانت تحتوي على اختبارات، ولكن لا توجد اختبارات لبرامج الاستيراد النصية.

إعجابَين (2)

مرحباً، للتوضيح فقط، لا أتوقع من أحد إصلاح هذا الآن (بأسلوب كارين). أنا فقط أشير إلى بعض الأشياء التي من الواضح أن لديها بعض المشاكل في قاعدة التعليمات البرمجية نفسها ومن المحتمل أنها مجرد "عفوًا، لقد نسيت إضافة هذا التغيير إلى الالتزام! :sweat_smile: "
لقد قبلت بالفعل أن هذه الهجرة لن تحدث قبل يناير، على الأقل، في هذه المرحلة.
يجب على الجميع الاستمتاع بالعطلات :slight_smile:
سأثير هذا الأمر أو أفتح موضوعًا جديدًا بعد العطلات حتى لو كان لدي بالتأكيد وقت أقل لتكريسه لهذه الهجرة :frowning:

إعجابَين (2)

نعم، هذا صحيح تمامًا - بالنسبة للواردات، عادةً لا أقدم طلب سحب قبل أن أقوم باستيرادين من عميلين مختلفين.

إعجاب واحد (1)

جارٍ تحديث هذا.

لقد أجريت بعض التغييرات على base.rb بعد مناقشتها مع بعض المهندسين الآخرين في مجتمعنا. تسببت العديد من الأخطاء في فشل gsub! بسبب وجود مواضيع بعنوان '' على ما يبدو.

أضفنا دالة تحاكي الدالة normalize_text التي تعيد ببساطة imported_id للموضوع إذا لم يكن هناك محتوى، محولة إلى سلسلة نصية.

  def normalize_text_thread(text, imported_id)
    return imported_id.to_s unless text.present?
    @html_entities.decode(normalize_charset(text.presence || "").scrub)
  end

ثم في vbulletin5.rb غيرنا السطر في create_topic إلى:

create_topics(topics) do |row|
      created_at = Time.zone.at(row[5])

      title = normalize_text_thread(row[1], row[0])

لقد تخلص ذلك من المشكلة. بشكل أساسي، لا يتعامل gsub! جيدًا مع تلقي nil كمدخل.

ومع ذلك، هذا جعل البرنامج النصي يستمر ولكن عندما وصل إلى import_private_topics توقف هناك. هناك 253,427 موضوعًا خاصًا (رسالة خاصة) في قاعدة بياناتنا، وهي أقل بكثير من عدد الردود. بعد 9 ساعات، أوقفت البرنامج النصي لمعرفة ما كان يحدث بالفعل.

عند تشغيل الواجهة، لاحظت بعض الأشياء.

  1. لم يتم استيراد حسابي لأن المسؤول الذي تم إنشاؤه كان يستخدم نفس البريد الإلكتروني على ما أعتقد. هذا واضح ولكنه شيء يجب كتابته في مكان ما ربما؟
  2. تم استيراد بعض الفئات فقط (منتديات vbulletin الفرعية).
  3. تم استيراد المواضيع وردها الأول فقط (لست متأكدًا مما إذا كانت كلها حقًا) وتم استيرادها جميعًا دون أن تكون في الفئات الصحيحة، حتى تلك التي كانت لها فئة كان من الممكن إنشاؤها. تم استيراد كل شيء “بدون فئة”.
  4. يظهر “عداد الردود” -1، ربما لأن الردود لم يتم استيرادها على الإطلاق.

سأضيف بشكل عام، الكثير من المشاكل مع هذا المستورد المجمع ستختفي إذا تم تطبيق نهج تقسيم الصفحات. أعتقد أن الردود قد فُقدت لأن البرنامج النصي حاول المرور عليها كلها دفعة واحدة ومع 7 جيجابايت من البيانات كان ذلك مستحيلاً. من المدهش بالنسبة لي أن مستوردًا مجمعًا لا يتعامل مع الاستيراد بنهج تقسيم الصفحات بصراحة. حتى مجرد أخذ 1000 سجل في المرة الواحدة، وكتابتها وتخزين معرف آخر سجل مكتوب وتكراره سيحل أي مشكلة مع قواعد البيانات الكبيرة.

إعجاب واحد (1)

للعلم، أنا أتابع هذا باهتمام، وأقدر التحديثات جدًا. :pray: لا أعرف الكثير عن الهجرات حتى الآن، لكني أجد هذا مفيدًا جدًا.

4 إعجابات