مُستورِد جماعي لـVbulletin: القيمة NULL في عمود "pinned_globally" في الجدول "topics" ينتهك قيد عدم القبول للقيمة الفارغة

أحاول إجراء استيراد باستخدام مستورد vbulletin المجمع. لقد تمكنت من جعله يقوم بذلك في الغالب. لقد أنشأ مستخدمين ومنشورات، ولكن لم يتم إنشاء مواضيع.

الأشياء التي يتم تمريرها إلى create_topics(topics) تبدو صحيحة. الأشياء الموجودة في processed في base.rb:create_records تبدو صحيحة (لم يتم تعيين skipped). ولكن لم يتم إنشاء أي مواضيع.

هذا هو الخطأ:

ERROR:  null value in column "pinned_globally" of relation "topics" violates not-null constraint

ولكن إذا لم يكن الموضوع مثبتًا عالميًا، فما القيمة التي يجب أن يحصل عليها؟ أحاول التعليق على هذا الحقل في TOPIC_COLUMNS في base.rb.

تحرير: أعتقد أن هذا قد ينجح ولكني لن أعرف لفترة:

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

      t = {
        imported_id: row[0],
        title: normalize_text(row[1]),
        category_id: category_id_from_imported_id(row[2]),
        user_id: user_id_from_imported_id(row[3]),
        closed: row[4] == 0,
        created_at: created_at,
        views: row[6] || 0,
        visible: row[7] == 1,
        pinned_globally: row[8] == 1 # <============== JP أضاف هذا:
      }
      t[:pinned_at] = created_at if row[8] == 1

      t
    end

هذا غريب، بما أن هذا العمود له قيمة افتراضية؟ هل له قيمة افتراضية في قاعدة بياناتك عند تشغيل \\d topics؟

pinned_globally | boolean | | not null | false

أوه. هذا يفسر سبب عدم وجوده في الكود، أعتقد.

لكن هذا لا يحل اللغز.

pinned_globally    | boolean   |     | not null | false

تعديل:

يقول الذكاء الاصطناعي العشوائي:

ربما هذه “أداة إدراج مجمعة”؟

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

ها هي الوثائق الفعلية! PostgreSQL: Documentation: 18: COPY

إذا تم تحديد قائمة أعمدة، فإن COPY TO ينسخ فقط البيانات في الأعمدة المحددة إلى الملف. بالنسبة إلى COPY FROM، يتم إدراج كل حقل في الملف، بالترتيب، في العمود المحدد. ستتلقى أعمدة الجدول غير المحددة في قائمة أعمدة COPY FROM قيمها الافتراضية.

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

إنه يصبح أبطأ وأبطأ. هل هناك سبب لعدم استخدام LIMIT 1000 كما يفعل المستورد العادي؟ يبدو أن 885 ألف موضوع ربما يكون كثيرًا جدًا دفعة واحدة؟

لقد تحققت من النص البرمجي لآخر استيراد جماعي قمت به، وهو يحتوي بالفعل على pinned_globally: false بشكل صريح، لذا يبدو أنه ضروري - إنه القيمة الحاسمة المعرّفة يدويًا في الكود.

    create_topics(topics) do |row|
      t = {
        imported_id: row[0],
        title: my_normalize_text(row[1]),
        category_id: category_id_from_imported_id(row[2]),
        user_id: user_id_from_imported_id(row[3]),
        created_at: Time.zone.at(row[4]),
        pinned_globally: false
      }

من الغريب أنه لا يوجد هذا في أعمدة أخرى مماثلة تحتوي على not null, default false مثل closed أو has_summary.

[اقتباس=“pfaffman، المشاركة:3، الموضوع:366162”]
يبطئ الأمر تدريجيًا وأكثر وأكثر. هل هناك سبب لعدم استخدام LIMIT 1000 كما يفعل المستورد العادي؟ يبدو أن 885 ألف موضوع هو عدد كبير لالتقاطه دفعة واحدة؟
[/اقتباس]
آخر استيراد قمت به باستخدام أداة الاستيراد الجماعي استغرق أكثر من 2 ساعة ليتجاوز 3 ملايين موضوع. ربما لديك تسرب ذاكرة؟ أو ربما يكون كود MySQL الخاص بك (أو أي أداة تستخدمها لقراءة البيانات المصدر) بطيئًا في مكان معين؟

أخبار سارة! تم إنشاء جميع المواضيع! أخبار سيئة! لم يتم ربط أي من المنشورات بها، ولكن نأمل أن يكون ذلك بسبب إنشاء المنشورات قبل المواضيع.

هذا غريب. كنت متأكدًا من أن لدي تفسيرًا. :person_shrugging:

استغرقت 7 ملايين منشور بضع ساعات فقط، لكن أقل من مليون موضوع استغرقت حوالي 4 ساعات.

إنها آلة قديمة (يبدو أنهم اشتروها فقط لهذه المهمة؟)، و mysql بعيد. بالنظر إلى htop لا يوجد تسرب واضح في الذاكرة على مستوى النظام. لقد قمت بمسح جميع البيانات وأقوم بإعادة بناء الحاويات لمعرفة ما إذا كان سيعمل هذه المرة.

شكرًا جزيلاً على مساعدتك.

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

حسنًا، الآن استيراد user_email يفشل مع الرسالة:

السياق:  نسخ user_emails، السطر 1: "1  \N      @gmail.com     true    2004-03-08 14:12:00 UTC 2004-03-08 14:12:00 UTC"

لقد استغرقت عدة ساعات أخرى، ولكن ها هو السبب - الدالة process_topic تتعامل مع كل هذه القيم الافتراضية.

أعتقد أنه يجب أن يكون هناك

topic[:pinned_globally] ||= false

أو ربما

topic[:pinned_globally] ||= topic[:pinned_at].nil?
إعجاب واحد (1)