Eliminar todos los posts de un tipo de post personalizado de manera eficiente

13 nov 2015, 23:29:59
Vistas: 48.9K
Votos: 26

Estoy buscando una forma segura y rápida de eliminar todos los posts de un tipo de post personalizado. Usar get_posts() y wp_delete_post() para cada post devuelto no funciona; no es lo suficientemente rápido debido a la gran cantidad de consultas a la base de datos involucradas (error de timeout).

Preferiblemente, busco ejecutar una única consulta a la base de datos que elimine todos los posts que son de un tipo de post personalizado. ¿Alguna sugerencia?

9
Comentarios

¿Es esto un evento único? Si es así, una consulta SQL rápida a través de phpMyAdmin parece lo más sencillo. Si este es un paso de mantenimiento que necesita hacerse programáticamente/de forma repetida, eso no te ayudará.

jdm2112 jdm2112
13 nov 2015 23:53:56

Desafortunadamente, necesita hacerse regularmente, sin acceso manual a la base de datos.

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

Entendido. Recomendaría mirar la clase wpdb entonces. Es el método preferido y "la forma WP" para trabajar directamente con la base de datos. Avísanos si necesitas ayuda con esa consulta. Puedo publicar una respuesta completa más tarde si es necesario https://codex.wordpress.org/Class_Reference/wpdb

jdm2112 jdm2112
14 nov 2015 00:14:04

¿Cuántas publicaciones necesitas eliminar? ¿Y con qué frecuencia? Una consulta SQL directa podría ser rápida, pero a menos que tengas mucho, mucho cuidado, dejarás datos huérfanos en toda la base de datos. Y WordPress guarda datos en muchas tablas con algunas interconexiones complicadas.

s_ha_dum s_ha_dum
14 nov 2015 04:41:44

Usa 'fields' => 'ids', en get_posts para obtener solo el ID de la publicación. Esto es todo lo que necesitas y acelerará significativamente tu consulta.

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

@s_ha_dum Los datos huérfanos son lo que obviamente estoy tratando de evitar. Estoy eliminando alrededor de 5.5K publicaciones (y agregando alrededor de 5.5K publicaciones, así que si tienes una solución para eso, soy todo oídos). Es una operación de sincronización que ocurre en intervalos arbitrarios. Podría suceder una vez a la semana o una vez al mes.

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

@PieterGoosen Buen punto, lo intentaré y veré a dónde me lleva. Pero sospecho que una sola consulta será mucho más eficiente.

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

@jdm2112 Probablemente no podré ocuparme de esto hasta el lunes, pero esto parece ser el camino a seguir. Gracias.

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

@MarcusMcLean : obviamente, no entendiste mi punto ;) Un solo post tiene datos en la tabla posts, la tabla postmeta, la(s) tabla(s) de taxonomía, y posiblemente la tabla de opciones. Cualquier consulta SQL pura que escribas para eliminar esos posts será bastante complicada. Existe una buena posibilidad de dejar cosas atrás en esas diversas tablas. Yo intentaría eliminar, digamos, 50 a la vez con intervalos de 5 minutos usando las funciones principales y wp_cron()

s_ha_dum s_ha_dum
14 nov 2015 06:08:16
Mostrar los 4 comentarios restantes
Todas las respuestas a la pregunta 4
4
43

Puedes eliminar todas las publicaciones mediante $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)

o usa esta consulta reemplazando {{your CPT}} con tu Tipo de Publicación Personalizado

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
Comentarios

esto probablemente funcionaría bien, pero no olvides los conteos de términos en una de las tablas de términos. WordPress debería tener una función para actualizar esto.

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

los usuarios también tienen conteos de publicaciones en la pantalla de usuarios, no estoy seguro si estos datos se guardan previamente o se calculan al cargar la página.

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

@JoelM La columna de conteo existe en la tabla de la base de datos wp_term_taxonomy. Parece que la función que buscas para actualizar el conteo es wp_update_term_count($terms, $taxonomy, false) o wp_update_term_count_now($terms, $taxonomy) definida en wp-includes/taxonomy.php.

Ken Ken
24 jul 2019 14:46:33

es más seguro usar el comando WP CLI, revisa la otra respuesta

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

Esto ahora puede realizarse con la CLI de WordPress utilizando el comando wp post delete. Una vez que la CLI está instalada, el siguiente comando en la terminal (mientras te encuentras en el directorio raíz de tu sitio) eliminará todas las entradas del tipo mycustomtype:

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

Sin SQL directo (*horror*), sin preocuparte por tiempos de espera, y es rápido. Por ejemplo, acabo de eliminar ~2500 entradas en menos de dos minutos.

Para omitir la Papelera y eliminarlas completamente usa --force

4 jun 2020 18:53:01
Comentarios

Esto funcionó para mí para eliminar ~12k publicaciones. Lo manejó sin problemas. Usa la bandera --force si quieres omitir la "papelera" y eliminarlos permanentemente.

squarecandy squarecandy
18 sept 2020 17:09:06

bash: /usr/local/bin/wp: Argument list too long 200K publicaciones en mi caso... Casi lo logro :)

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

Puedes eliminar todas las entradas de un tipo de contenido personalizado (custom post type) de varias formas, pero aquí te mostraré cómo hacerlo sin usar consultas SQL. En este ejemplo, nuestro tipo de contenido es producto (product).

$allposts = get_posts( array('post_type'=>'producto','numberposts'=>-1) );
foreach ($allposts as $eachpost) {
    wp_delete_post( $eachpost->ID, true );
}

Ver tutorial completo de referencia aquí

2 oct 2018 20:28:36
Comentarios

Lee nuevamente la OP: "Usar get_posts() y wp_delete_post() para cada publicación devuelta no funciona; no es lo suficientemente rápido debido a la gran cantidad de consultas a la base de datos involucradas (error de tiempo de espera)."

Estás usando las dos funciones que él no quiere usar.

Mike Mike
2 nov 2018 10:19:17

Tienes toda la razón. Pero solo para estar seguros y también eliminar con términos, comentarios y metadatos con recuento en términos. Es el método perfecto. Tal vez podríamos usar cron para ello.

pathusutariya pathusutariya
4 mar 2021 08:29:00

Si pasas 'fields' => 'ids' a get_posts, entonces devolverá un array de IDs en lugar de un array de objetos de publicación, lo que debería acelerar un poco este proceso.

Flimm Flimm
13 jul 2022 17:45:07
0

Si has prefijado tu tipo de post CPT y tus taxonomías CPT con algo como 'abc_mi_tipo_post_personalizado' y 'abc_mi_taxonomia', entonces es trivial eliminar todo de la base de datos con dos consultas:

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