Eliminare definitivamente i post eliminati in blocco?

If I am not mistaken there is a field called deleted_at

If it is deleted, then there should be a date time Stamp.

If it is not deleted then is null

Maybe look for the entry that is <> Null and delete

1 Mi Piace

Thanks Gav, but the ones that I am targeting aren’t marked as deleted. Rather, their Topic has been deleted and then destroy_all’d.

2 Mi Piace

I was playing around with this and i notice that part of your query was not returning the response you need.

SELECT topic_id from posts does not return an integer, but it returned a string

image

This might be the cause that your db still contains orphaned posts.

2 Mi Piace

Penso che tu stia vedendo Data Explorer convertire automaticamente l’intero in un URL, cosa che fa quando l’etichetta è topic_id.

Quando eseguo questa query in Data Explorer, tutti i post che sto cercando di identificare vengono acquisiti (ben oltre 5000):

SELECT id, topic_id
FROM posts
WHERE topic_id not in (select id from topics)
ORDER by id

Sto chiaramente facendo qualcosa di sbagliato con la mia sintassi Rails poiché questo è ciò che sto ottenendo:

[1] pry(main)=> Target = Post.where('topic_id not in (select id from topics)')
=> []

Qualcuno può dirmi cosa sto facendo di sbagliato?

1 Mi Piace

Bene, grazie a @pfaffman ho identificato i post pertinenti usando questo:

Post.find_by_sql("select id from posts where topic_id not in (select id from topics)")

Ottengo questo output:

[1] pry(main)> Post.find_by_sql(“select id from posts where topic_id not in (select id from topics)”)
=> [#<Post:0x000055df30d4ee90 id: 150>,
#<Post:0x000055df2e538ff0 id: 51097>,
#<Post:0x000055df2e50ba28 id: 83>,
#<Post:0x000055df2e4ee8b0 id: 40636>,
#<Post:0x000055df2e4a92d8 id: 62562>,
#<Post:0x000055df2e4b7978 id: 13522>,
ecc.

Tuttavia, non riesco a capire come applicare destroy_all a questa selezione.

Questo potrebbe aiutare (a mio beneficio):

Qualsiasi suggerimento?

1 Mi Piace

Penso che questo funzionerà

posts=
Post.find_by_sql("select id from posts where topic_id not in (select id from topics)")


posts.destroy_all

Oppure potresti aggiungere .destroy_all al tuo find_by_sql

2 Mi Piace

Ci ho provato. I dati sembrano essere restituiti come un array con un identificatore di post e un ID (vedi Delete deleted-posts permanently in bulk? - #45 by nathank).

Questo è l’errore che ricevo quando aggiungo .destroy_all o uso il posts= che suggerisci:

[2] pry(main)> posts.destroy_all
NoMethodError: undefined method destroy_all' for #<Array:0x000055fe7bc7fc98> from (pry):3:in pry

1 Mi Piace

Oh. Allora forse controlla se

 p=posts.first

È un post_id. Se è così, allora puoi

x=Post.find(p)
x.destroy

Quindi potresti ciclare attraverso quelli.

Penso che dovresti racchiudere la tua query in qualcosa per farla diventare un array di post piuttosto che di post_id.

1 Mi Piace

Grazie Jay. Questo è quello che ottengo:

\u003e[3] pry(main)\u003e p=\n[3] pry(main)* posts.first\n=\u003e #\u003cPost:0x0000563a24cab908 id: 150\u003e\n[4] pry(main)\u003e x=Post.find(p)\nArgumentError: Stai passando un’istanza di ActiveRecord::Base a find. Per favore, passa l’id dell’oggetto chiamando .id.\nfrom /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/activerecord-6.1.4.1/lib/active_record/relation/finder_methods.rb:467:in `find_one’\n

Ora, parlami di queste cose di wrap. È così fastidioso, perché so che il comando rails di @Sam qui dovrebbe funzionare, ma penso che Rails sia cambiato da allora:

1 Mi Piace

Cosa ha fatto? Non riesco a immaginare che Rails sia cambiato.

1 Mi Piace

Questo ti restituisce i post che vuoi eliminare?

1 Mi Piace

Ho letto da qualche parte online, cercando come convertire un Active Record Array in una Active Record Relation, che le cose sono cambiate tra Rails 3.x e Rails 4 e la sintassi deve essere diversa, ma mi è sfuggita davvero.

Ne ha raccolti alcuni quando l’ho eseguito per la prima volta e li ho regolarmente destroy_allati. Ma non erano molti. Ora non ne raccoglie nessuno, mentre l’SQL ne raccoglie migliaia quando eseguito in Data Explorer.

Questi sono Post orfani, dove il Topic è stato Destroy_allato.

1 Mi Piace

Puoi usare each{} per iterare sui membri di quell’array, chiamando destroy su ogni post individualmente?

Post.find_by_sql(“select id from posts where topic_id not in (select id from topics)”).each { |p| p.destroy }
2 Mi Piace

Beh, ci ho provato. Prima non gli piaceva l’SQL racchiuso in quel modo né la sintassi:

Post.find_by_sql(“select id from posts where topic_id not in (select id from topics)”).each { |p| p.destroy_all }
SyntaxError: unexpected `in’, expecting ‘(’
…rom posts where topic_id not in (select id from topics)”)…
… ^~
SyntaxError: unexpected local variable or method, expecting end-of-input
…t in (select id from topics)”).each { |p| p.destroy_all }

Quindi ho fatto un altro tentativo “hacky” dividendolo:

posts=Post.find_by_sql("select id from posts where topic_id not in (select id from topics)")
posts.each do |p|
p.destroy
end

Questo sembrava funzionare bene, ma l’aggiunta di p.destroy solleva questo:

ActiveModel::MissingAttributeError: missing attribute: user_id
from /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/activemodel-6.1.4.1/lib/active_model/attribute.rb:222:in `value’

Ho provato alcuni modi per inserirlo lì ma poi ho rinunciato. @sam, puoi aiutare?

P.S.

Ho persino provato a convertire l’SQL in AR tramite scuttle.io come da questo:

Post.select([:id, :topic_id]).where(Topic.select(:id))

Ahimè, ottengo questo errore:

ArgumentError: Unsupported argument type: #Topic::ActiveRecord_Relation:0x000055c67a7131d0 (Topic::ActiveRecord_Relation)

3 Mi Piace

Quando ho copiato e incollato quella parte da un messaggio precedente, sembra che le virgolette siano state convertite in virgolette ricce da qualche parte, mi aspetto che questo sia il vero errore. Mi dispiace per questo.

find_by_sql è descritto come il ritorno di un oggetto con i valori specificati nella query SQL, il che presumibilmente significa che si ottiene un oggetto Post con solo la proprietà id impostata, user_id e tutto il resto è mancante.

... find_by_sql("select * ... se ne occuperà. Probabilmente c’è un sottoinsieme di valori che potresti selezionare per ottenere un destroy, piuttosto che selezionare tutto, ma non so quale sia quel sottoinsieme.

Quindi l’intera cosa: (questa volta senza virgolette ricce…)

Post.find_by_sql("select * from posts where topic_id not in (select id from topics)").each { |p| p.destroy }
4 Mi Piace

:partying_face: Alleluia!!! :partying_face:

Grazie Simon, ha funzionato alla grande. I post orfani sono spariti e prevedo che i miei upload si ridurranno quasi a nulla nelle prossime 24 ore circa.

più tardi
E così è stato! Da 3,5 GB a 0,7 GB. Fantastico!!

7 Mi Piace

Eccellente, sono lieto di sentire che ha funzionato per te. Quindi, per combinare le risposte, si può usare quanto segue nella console Rails per eliminare tutti gli argomenti che sono stati eliminati più di 90 giorni fa, ripetendo quante volte necessario se ci sono più di 1000 argomenti:

Topic.with_deleted.where(deleted_at: ...90.days.ago).limit(1000).destroy_all

Dopo che questo è stato completato, si può usare quanto segue per eliminare tutti i post che sono stati orfani da argomenti eliminati:

Post.find_by_sql("select * from posts where topic_id not in (select id from topics)").each { |p| p.destroy }

Vale la pena notare che i comandi sopra non elimineranno i post eliminati, ma solo gli argomenti eliminati e i loro post orfani. Per eliminare anche i post eliminati più vecchi di 90 giorni, usa quanto segue, ripetendo ancora se necessario:

Post.with_deleted.where(deleted_at: ...90.days.ago).limit(1000).destroy_all

P.S. Per curiosità, hai provato destroy_all senza limit(1000) e hai avuto problemi o non l’hai provato senza il limite?

8 Mi Piace

Ho provato senza il limite e qualcosa è andato un po’ fuori controllo, ma dimentico i dettagli, mi dispiace.

Possiamo contrassegnare il tuo post come soluzione o utilizzare questo dall’OP?

image

3 Mi Piace

Non preoccuparti. Se non ci avessi provato, avrei aggiunto una nota che il limite potrebbe non essere necessario, ma dato che hai avuto problemi, posso lasciarlo così com’è.

1 Mi Piace

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.