Errore di migrazione: `ActiveRecord::NotNullViolation: PG::NotNullViolation: ERRORE: la colonna "private_message" contiene valori null`

Sto eseguendo un aggiornamento su un sito e sta fallendo con PG::NotNullViolation: ERROR: la colonna "private_message" contiene valori null. Non riesco a trovare dove esiste la colonna private_message. Non ci sono plugin non ufficiali.

Ah, aspetta. Ecco questo:

(Per vedere la traccia completa, esegui l'attività con --trace)                                                                                            
I, [2020-08-18T18:19:13.253667 #1]  INFO -- : == 20200818084329 UpdatePrivateMessageOnPostSearchData: migrazione ============= 
-- 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)

Ciao @tgxworld, penso che questo possa essere dovuto a

Hmm, questa è strana… puoi eseguire le seguenti query nella console di Rails e fornirmi i risultati?

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

Sembra che l’ultimo conteggio non sia stato eseguito.

Scusa. Continuo ad avere problemi con il click-to-copy perché non include l’a capo del terminale.

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

Scusa se devi eseguire tutte le query insieme :slight_smile: altrimenti, la creazione di nuovi post altererà il conteggio.

È così ovvio quando lo dici… E fare solo quella singola query ha richiesto più lavoro!

[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 Voglio solo confermare che questo è stato risolto come da nostro PM?

Scusa, Alan. Sì, questo è stato risolto. Grazie per il tuo aiuto in questo caso!

Per chiunque altro abbia questo problema, se esegui un semplice ./launcher rebuild app, non dovresti avere problemi, tranne che il tuo sito potrebbe essere offline per molto tempo mentre la parte di bootstrap del rebuild migra il database. Questa è l’opzione sicura e semplice, ed è quello che farai comunque a meno che tu non abbia un’installazione a 2 container.

Non volevo tenere il sito offline per l’intero bootstrap. Per questo forum di grandi dimensioni (5 milioni di post e ~50.000 visualizzazioni di pagina al giorno?), la mia soluzione (che ho scoperto solo con l’aiuto di Alan) è stata avviare il bootstrap con le migrazioni post-aggiornamento disattivate (le migrazioni hanno richiesto praticamente zero tempo), avviare il nuovo container ed eseguire le migrazioni post-aggiornamento (le migrazioni hanno richiesto 20-40 minuti – non ho davvero prestato attenzione all’orologio).

Se a qualcun altro interessa, ho scoperto che eseguire l’aggiornamento con docker_manager lo farà in modo molto più fluido, quindi questo è ciò che consiglierei a chiunque abbia un forum di grandi dimensioni e problemi con il bootstrap.