مشكلة استيراد غريبة -- استعلام MySQL يُرجع PG::Result؟

هذا الأمر محير لي. إليك دالة mysql_query:

  def mysql_query(sql)
    begin
      #puts "Query: \n#{sql}"
      @client.query(sql, cache_rows: true)
    rescue Exception => ex
      begin
        ActiveRecord::Base.connection.reconnect!
      rescue
        puts "فشل الاتصال بقاعدة البيانات، سيتم إعادة المحاولة خلال 10 ثوانٍ"
        sleep 10
        puts "حان وقت إعادة المحاولة..."
        @client.query(sql, cache_rows: true)
      end
    end
  end

تم استيراد أول 5 ملايين منشور تقريبًا بنجاح، لكن الآن، في كثير من الأحيان،

        posts = mysql_query(query).to_a

لا يُرجع نتيجة MySQL، بل يُرجع بدلاً من ذلك:

 [#<PG::Result:0x0000563f3ee6d8d0 status=PGRES_COMMAND_OK ntuples=0 nfields=0 cmd_tuples=0>]

لقد لجأت إلى الحل التالي:

      while !posts[-1].is_a?(Hash)
        puts "Posts: #{posts}"
        ActiveRecord::Base.connection.reconnect!
        @mysql_client = Mysql2::Client.new(
          host: DB_HOST,
          username: DB_USER,
          password: DB_PW,
          database: DB_NAME
        )
        posts = mysql_query(query).to_a
      end

وهذا الحل يكتشف المشكلة ويحلها، لكنه لا يزال يفشل في كل استعلام تقريبًا (أحيانًا تنجح 3 استعلامات تحتوي كل منها على 5000 سجل). كتبتها على شكل حلقة تكرار، لكنني أعتقد أنها لم تُنفذ أكثر من مرة. ظننت للحظة أن شيئًا آخر يستخدم @client ويضع استعلام PG فيه، لذا قمت بالتبديل إلى @mysql_client، لكن ذلك لم يحل المشكلة.

لقد بحثت قليلًا عبر الإنترنت ولم أجد شيئًا.

حلي التجريبي يعمل، لذا أعتقد أنه “تم إصلاحه”، لكنني لا أزال فضوليًا بشأن ما قد يسبب هذه المشكلة.

لماذا؟! هذا الاستدعاء يعيد الاتصال بقاعدة بيانات PostgreSQL ويعيد لك كائن PG::Result الذي تراه. إن حيلتك هذه لا تفعل سوى إخفاء حقيقة أنك تقوم بشيء أحمق لا ينبغي لك فعله. :wink:

أظن أن ما تبحث عنه حقًا هو خيار الاتصال reconnect خيار الاتصال الخاص بعميل mysql2.

آه! إذن ربما يكون الكود الخاص بي الذي يفترض أن يلتقط أخطاء MySQL ويعيد المحاولة هو المسؤول. اعتقدت أن هذا الكود كان يعمل سابقًا. وما زلت أنسى أن الدالة تعيد قيمة السطر الأخير الذي يتم تنفيذه.

شكرًا جزيلًا لك، @gerhard. سيستغرق الأمر ما لا يقل عن 15 دقيقة قبل أن أرى ما سيحدث بعد ذلك، لكن على الأقل فهمت الآن من أين جاء إرجاع PG!