Eliminare tutti i post di un custom post type in modo efficiente

13 nov 2015, 23:29:59
Visualizzazioni: 48.9K
Voti: 26

Sto cercando un modo sicuro e veloce per eliminare tutti i post di un determinato custom post type. Utilizzare get_posts() e wp_delete_post() per ogni post restituito non funziona; non è abbastanza veloce a causa dell'enorme quantità di query al database coinvolte (errore di timeout).

Preferibilmente, sto cercando una singola query al database da eseguire che elimini tutti i post di un custom post type. Qualche suggerimento?

9
Commenti

È un evento una tantum? In tal caso, una rapida query SQL via phpMyAdmin sembra la soluzione più semplice. Se invece si tratta di un'operazione di manutenzione da eseguire programmaticamente/ripetutamente, questo approccio non ti sarà d'aiuto.

jdm2112 jdm2112
13 nov 2015 23:53:56

Purtroppo deve essere eseguita regolarmente, senza accesso manuale al database.

Marcus McLean Marcus McLean
14 nov 2015 00:03:30

Ricevuto. Consiglierei di considerare la classe wpdb. È il metodo preferito e "alla WordPress" per lavorare direttamente con il database. Faccici sapere se hai bisogno di aiuto con quella query. Posso postare una risposta completa più tardi se necessario https://codex.wordpress.org/Class_Reference/wpdb

jdm2112 jdm2112
14 nov 2015 00:14:04

Quanti post hai bisogno di eliminare? E con quale frequenza? Una query SQL diretta potrebbe essere veloce ma, a meno che tu non sia molto, molto attento, lascerai dati orfani in tutto il database. E WordPress mantiene i dati in molte tabelle con alcuni collegamenti incrociati complicati.

s_ha_dum s_ha_dum
14 nov 2015 04:41:44

Usa 'fields' => 'ids', in get_posts per ottenere solo gli ID dei post. Questo è tutto ciò di cui hai bisogno e velocizzerà significativamente la tua query

Pieter Goosen Pieter Goosen
14 nov 2015 05:09:12

@s_ha_dum I dati orfani sono proprio ciò che sto cercando di evitare, ovviamente. Sto eliminando circa 5.5K post (e aggiungendone altrettanti, quindi se hai una soluzione anche per quello, sono tutto orecchi). È un'operazione di sincronizzazione che avviene a intervalli arbitrari. Potrebbe succedere una volta a settimana o una volta al mese.

Marcus McLean Marcus McLean
14 nov 2015 05:59:57

@PieterGoosen Ottimo punto, proverò così e vedrò dove mi porta. Ma sospetto che una singola query sarà molto più efficiente.

Marcus McLean Marcus McLean
14 nov 2015 06:00:23

@jdm2112 Probabilmente non riuscirò a occuparmene prima di lunedì, ma questa sembra la strada giusta. Grazie.

Marcus McLean Marcus McLean
14 nov 2015 06:01:19

@MarcusMcLean : ovviamente, hai perso il punto ;) Un singolo post ha dati nella tabella posts, nella tabella postmeta, nella/e tabella/e taxonomy e possibilmente nella tabella options. Qualsiasi query SQL pura che scrivi per eliminare quei post sarà piuttosto complicata. Hai buone probabilità di lasciare cose indietro in quelle varie tabelle. Proverei a eliminare, diciamo, 50 alla volta a intervalli di 5 minuti usando le funzioni Core e wp_cron()

s_ha_dum s_ha_dum
14 nov 2015 06:08:16
Mostra i restanti 4 commenti
Tutte le risposte alla domanda 4
4
43

Puoi eliminare tutti i post tramite $wpdb

DELETE FROM wp_posts WHERE post_type='post_type';
DELETE FROM wp_postmeta WHERE post_id NOT IN (SELECT id FROM wp_posts);
DELETE FROM wp_term_relationships WHERE object_id NOT IN (SELECT id FROM wp_posts)

oppure usa questa query sostituendo {{your CPT}} con il tuo Custom Post Type

DELETE a,b,c
    FROM wp_posts a
    LEFT JOIN wp_term_relationships b
        ON (a.ID = b.object_id)
    LEFT JOIN wp_postmeta c
        ON (a.ID = c.post_id)
    WHERE a.post_type = '{{your CPT}}';
2 ago 2017 20:07:38
Commenti

questo probabilmente funzionerebbe bene, ma non dimenticare i conteggi dei termini in una delle tabelle dei termini. WordPress dovrebbe avere una funzione per aggiornare questo valore.

Joel M Joel M
28 feb 2018 21:37:50

gli utenti hanno anche conteggi di articoli nella schermata degli utenti, non sono sicuro se questi dati siano salvati in anticipo o calcolati durante il caricamento della pagina.

Joel M Joel M
28 feb 2018 21:39:03

@JoelM La colonna del conteggio esiste nella tabella del database wp_term_taxonomy. Sembra che la funzione che stai cercando per aggiornare il conteggio sia wp_update_term_count($terms, $taxonomy, false) o wp_update_term_count_now($terms, $taxonomy) definita in wp-includes/taxonomy.php.

Ken Ken
24 lug 2019 14:46:33

più sicuro utilizzare il comando WP CLI, controlla l'altra risposta

Mladen Janjetovic Mladen Janjetovic
30 mag 2024 16:07:15
2
23

Questo può ora essere fatto utilizzando la CLI di WordPress con il comando wp post delete. Una volta installata la CLI, il seguente comando da terminale (eseguito nella directory root del tuo sito) eliminerà tutti i post di tipo mycustomtype:

wp post delete $(wp post list --post_type='mycustomtype' --format=ids)

Niente SQL grezzo (*brividi*), nessun problema di timeout ed è veloce. Ad esempio, ho appena eliminato ~2500 post in meno di due minuti.

Per saltare il Cestino ed eliminarli definitivamente usa --force

4 giu 2020 18:53:01
Commenti

Questo ha funzionato per me per eliminare ~12k post. Li ha gestiti senza problemi. Usa il flag --force se vuoi saltare il "cestino" ed eliminare definitivamente.

squarecandy squarecandy
18 set 2020 17:09:06

bash: /usr/local/bin/wp: Argument list too long 200K post nel mio caso... Ci sono quasi arrivato :)

SirLouen SirLouen
1 ago 2024 15:09:06
3
14

Puoi eliminare tutti i post di un custom post type in vari modi, ma qui ti mostrerò come farlo senza utilizzare query SQL. Ad esempio, qui il nostro post type è product

// Ottieni tutti i post del tipo 'product'
$allposts = get_posts( array('post_type'=>'product', 'numberposts'=>-1) );

// Elimina ogni post trovato
foreach ($allposts as $eachpost) {
    wp_delete_post( $eachpost->ID, true );
}

Vedi il tutorial completo qui

2 ott 2018 20:28:36
Commenti

Leggi di nuovo l'OP: "Usare get_posts() e wp_delete_post() per ogni post restituito non funziona; non è abbastanza veloce a causa dell'enorme quantità di query al database coinvolte (errore di timeout)."

Stai usando le due funzioni che non vuole utilizzare.

Mike Mike
2 nov 2018 10:19:17

Hai assolutamente ragione. Ma solo per andare sul sicuro e anche per eliminare con termini, commenti e meta con conteggio sui termini. È il metodo perfetto. Forse possiamo usare un cron per questo.

pathusutariya pathusutariya
4 mar 2021 08:29:00

Se passi 'fields' => 'ids' a get_posts, restituirà un array di ID invece di un array di oggetti post, il che dovrebbe velocizzare un po' le cose.

Flimm Flimm
13 lug 2022 17:45:07
0

Se hai prefissato il tuo post type personalizzato (CPT) e le tue tassonomie CPT con ad esempio 'abc_mio_post_type_personalizzato' e 'abc_mia_tassonomia', allora è banale rimuovere tutto dal database con due query:

DELETE a,b
FROM      $wpdb->posts    a
LEFT JOIN $wpdb->postmeta b ON a.ID = b.post_id
WHERE a.post_type LIKE 'abc_%';
            
DELETE a,b,c
FROM      $wpdb->term_taxonomy      a
LEFT JOIN $wpdb->term_relationships b ON a.term_taxonomy_id = b.term_taxonomy_id
LEFT JOIN $wpdb->terms              c ON a.term_id = c.term_id
WHERE a.taxonomy LIKE 'abc_%'
2 mar 2023 16:30:42