Migration-Fehler: `ActiveRecord::NotNullViolation: PG::NotNullViolation: FEHLER: Spalte „private_message“ enthält Nullwerte`

Ich führe ein Upgrade auf einer Site durch, und es schlägt fehl mit PG::NotNullViolation: ERROR: column "private_message" enthält NULL-Werte. Ich kann nicht finden, wo die Spalte private_message existiert. Es gibt keine nicht-offiziellen Plugins.

Ach so. Warte. Hier ist das:

(Siehe vollständigen Trace, indem Sie die Aufgabe mit --trace ausführen)                                                                                            
I, [2020-08-18T18:19:13.253667 #1]  INFO -- : == 20200818084329 UpdatePrivateMessageOnPostSearchData: Migration läuft ============= 
-- 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)

Hey @tgxworld, ich denke, das liegt möglicherweise an

Hmm, das ist seltsam… kannst du die folgenden Abfragen für mich in der Rails-Konsole ausführen und mir die Ergebnisse mitteilen?

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

Es sieht so aus, als wäre die letzte Zählung nicht ausgeführt worden.

Entschuldigung. Ich werde immer wieder davon erwischt, dass beim Klick zum Kopieren die Zeilenvorschub-Zeichen in der Terminalzeile nicht mitkopiert werden.

[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]

Tut uns leid, dass du alle Abfragen zusammen ausführen musst :slight_smile: Andernfalls würde die Erstellung neuer Beiträge die Zählung verfälschen.

Das ist so offensichtlich, wenn man es so sagt. . . Und es war mehr Arbeit, nur eine einzige Abfrage auszuführen!

[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 Ich möchte nur bestätigen, dass dies gemäß unserem PM geklärt wurde?

Entschuldigung, Alan. Ja, das Problem wurde gelöst. Vielen Dank für deine Hilfe dabei!

Für alle anderen mit diesem Problem: Wenn du einen einfachen ./launcher rebuild app ausführst, solltest du keine Schwierigkeiten haben, außer dass deine Website möglicherweise für eine lange Zeit offline ist, während der Bootstrap-Teil des Neubuilds die Datenbank migriert. Dies ist die sichere und einfache Option, und es sei denn, du hast eine 2-Container-Installation, wirst du ohnehin so vorgehen.

Ich wollte nicht, dass die Website während des gesamten Bootstrap-Vorgangs offline ist. Für dieses große Forum (5 Millionen Beiträge und ca. 50.000 Seitenaufrufe pro Tag?) war meine Lösung (die ich nur mit Alans Hilfe gefunden habe), den Bootstrap ohne nachträgliche Upgrade-Migrationen durchzuführen (die Migrationen dauerten praktisch keine Zeit), den neuen Container hochzufahren und dann die nachträglichen Upgrade-Migrationen durchzuführen (die Migrationen dauerten 20–40 Minuten – ich habe nicht wirklich auf die Uhr geachtet).

Falls es jemandem interessiert: Ich habe inzwischen gelernt, dass das Upgrade mit docker_manager dies viel reibungsloser erledigt. Das würde ich also empfehlen, falls jemand anderes ein großes Forum hat und Probleme beim Bootstrap-Vorgang hat.