خطأ في الترحيل: `ActiveRecord::NotNullViolation: PG::NotNullViolation: ERROR: column "private_message" contains null values`

أقوم بترقية موقع ما وفشلت العملية مع الرسالة PG::NotNullViolation: ERROR: column "private_message" contains null values. لا أستطيع العثور على مكان وجود عمود private_message. لا توجد إضافات غير رسمية.

أوه. انتظر. ها هو هذا:

(لمشاهدة التتبع الكامل، شغّل المهمة مع --trace)                                                                                            
I, [2020-08-18T18:19:13.253667 #1]  INFO -- : == 20200818084329 UpdatePrivateMessageOnPostSearchData: migrating ============= 
-- execute("DELETE FROM post_search_data\nWHERE post_id IN (\n  SELECT posts.id\n  FROM posts\n  LEFT JOIN topics ON topics.id = posts.topic_id\n  WHERE topics.id IS NULL\n)\n")
   -> 21.9072s                                                                                                       
-- execute("DELETE FROM post_search_data\nWHERE post_id IN (\n  SELECT post_search_data.post_id\n  FROM post_search_data\n  LEFT JOIN posts ON posts.id = post_search_data.post_id\n  WHERE posts.id IS NULL\n)\n")                                                                       
   -> 47.2663s
-- execute("UPDATE post_search_data\nSET private_message = true\nFROM posts\nINNER JOIN topics ON topics.id = posts.topic_id AND topics.archetype = 'private_message'\nWHERE posts.id = post_search_data.post_id\n")                                                                      
   -> 107.2137s             
-- execute("UPDATE post_search_data\nSET private_message = false\nFROM posts\nINNER JOIN topics ON topics.id = posts.topic_id AND topics.archetype <> 'private_message'\nWHERE posts.id = post_search_data.post_id\n")
   -> 834.3738s                                                                                                                              
-- change_column_null(:post_search_data, :private_message, false)

مرحبًا @tgxworld، أعتقد أن هذا قد يكون بسبب

همم، هذا غريب… هل يمكنك تشغيل الاستعلامات التالية لي في وحدة تحكم Rails وإمدادي بالنتائج؟

DB.query_single(<<~SQL)
SELECT COUNT(*) FROM post_search_data
SQL

DB.query_single(<<~SQL)
SELECT COUNT(*)
FROM post_search_data
LEFT JOIN posts ON posts.id = post_search_data.post_id
LEFT JOIN topics ON topics.id = posts.topic_id 
WHERE topics.id IS NULL
SQL

DB.query_single(<<~SQL)
SELECT COUNT(*)
FROM post_search_data
LEFT JOIN posts ON posts.id = post_search_data.post_id
WHERE posts.id IS NULL
SQL

DB.query_single(<<~SQL)
SELECT COUNT(*)
FROM post_search_data
INNER JOIN posts ON posts.id = post_search_data.post_id
INNER JOIN topics ON topics.id = posts.topic_id
SQL
[2] pry(main)> 
[3] pry(main)> DB.query_single(<<~SQL)
[3] pry(main)* SELECT COUNT(*) FROM post_search_data
[3] pry(main)* SQL
=> [2200178]
[4] pry(main)> 
[5] pry(main)> DB.query_single(<<~SQL)
[5] pry(main)* SELECT COUNT(*)
[5] pry(main)* FROM post_search_data
[5] pry(main)* LEFT JOIN posts ON posts.id = post_search_data.post_id
[5] pry(main)* LEFT JOIN topics ON topics.id = posts.topic_id 
[5] pry(main)* WHERE topics.id IS NULL
[5] pry(main)* SQL

=> [39]
[6] pry(main)> 
[7] pry(main)> DB.query_single(<<~SQL)
[7] pry(main)* SELECT COUNT(*)
[7] pry(main)* FROM post_search_data
[7] pry(main)* LEFT JOIN posts ON posts.id = post_search_data.post_id
[7] pry(main)* WHERE posts.id IS NULL
[7] pry(main)* SQL
=> [0]
[8] pry(main)> 
[9] pry(main)> DB.query_single(<<~SQL)
[9] pry(main)* SELECT COUNT(*)
[9] pry(main)* FROM post_search_data
[9] pry(main)* INNER JOIN posts ON posts.id = post_search_data.post_id
[9] pry(main)* INNER JOIN topics ON topics.id = posts.topic_id
[9] pry(main)* SQL

يبدو أن آخر عملية عد لم تُنفَّذ.

عذراً. لا أزال أواجه مشكلة في نسخ سطر الطرفية عند النقر للنسخ بسبب عدم تضمين سطر جديد.

[2] pry(main)> 
[3] pry(main)> DB.query_single(<<~SQL)
[3] pry(main)* SELECT COUNT(*)
[3] pry(main)* FROM post_search_data
[3] pry(main)* INNER JOIN posts ON posts.id = post_search_data.post_id
[3] pry(main)* INNER JOIN topics ON topics.id = posts.topic_id
[3] pry(main)* SQL
=> [2200797]

عذراً، يتعين عليك تشغيل جميع الاستعلامات معًا :slight_smile: وإلا فإن إنشاء منشورات جديدة سيؤدي إلى إرباك العدّ.

من الواضح جداً عندما تقول ذلك… وكان الأمر يتطلب جهداً أكبر لتشغيل استعلام واحد فقط!

[1] pry(main)> DB.query_single(<<~SQL)
[1] pry(main)* SELECT COUNT(*) FROM post_search_data
[1] pry(main)* SQL
=> [2200995]
[2] pry(main)> 
[3] pry(main)> DB.query_single(<<~SQL)
[3] pry(main)* SELECT COUNT(*)
[3] pry(main)* FROM post_search_data
[3] pry(main)* LEFT JOIN posts ON posts.id = post_search_data.post_id
[3] pry(main)* LEFT JOIN topics ON topics.id = posts.topic_id 
[3] pry(main)* WHERE topics.id IS NULL
[3] pry(main)* SQL
=> [39]
[4] pry(main)> 
[5] pry(main)> DB.query_single(<<~SQL)
[5] pry(main)* SELECT COUNT(*)
[5] pry(main)* FROM post_search_data
[5] pry(main)* LEFT JOIN posts ON posts.id = post_search_data.post_id
[5] pry(main)* WHERE posts.id IS NULL
[5] pry(main)* SQL
=> [0]
[6] pry(main)> 
[7] pry(main)> DB.query_single(<<~SQL)
[7] pry(main)* SELECT COUNT(*)
[7] pry(main)* FROM post_search_data
[7] pry(main)* INNER JOIN posts ON posts.id = post_search_data.post_id
[7] pry(main)* INNER JOIN topics ON topics.id = posts.topic_id
[7] pry(main)* SQL
=> [2200956]
[8] pry(main)> 

@pfaffman فقط أود التأكد من أن هذا تم حله وفقًا لخطة المشروع الخاصة بنا؟

عذرًا، آلن. نعم، تم حل هذه المشكلة بالفعل. شكرًا لك على مساعدتك في هذا الأمر!

بالنسبة لأي شخص آخر يواجه هذه المشكلة، إذا قمت بتشغيل الأمر العادي ./launcher rebuild app، فلن تواجه أي صعوبات، باستثناء احتمال توقف موقعك عن العمل لفترة طويلة أثناء عملية التمهيد (bootstrap) التي تنقل قاعدة البيانات. هذه هي الخطة الآمنة والسهلة، وهي ما ستفعله على أي حال ما لم تكن تستخدم تثبيتًا بحاويتين.

لم أكن أرغب في أن يكون موقعي متوقفًا طوال فترة التمهيد. وبالنسبة لهذا المنتدى الكبير (5 ملايين منشور وحوالي 50 ألف مشاهدة صفحة يوميًا؟)، كانت حلّي (الذي توصلت إليه بمساعدة آلن فقط) هو بدء التمهيد مع تعطيل ترقيات ما بعد التحديث (لم تأخذ الترقيات سوى وقت ضئيل جدًا)، ثم تشغيل الحاوية الجديدة وإجراء ترقيات ما بعد التحديث (استغرقت الترقيات 20-40 دقيقة - لم أكن أركز حقًا على الوقت).

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