Удаление всех записей произвольного типа записей—эффективный способ

13 нояб. 2015 г., 23:29:59
Просмотры: 48.9K
Голосов: 26

Я ищу безопасный и быстрый способ удаления всех записей одного произвольного типа. Использование get_posts() и wp_delete_post() для каждой полученной записи не работает; это недостаточно быстро из-за огромного количества запросов к базе данных (возникает ошибка тайм-аута).

Предпочтительно, я ищу единственный запрос к базе данных, который удалит все записи определенного произвольного типа. Есть какие-нибудь идеи?

9
Комментарии

Это разовое событие? Если да, то быстрый SQL-запрос через phpMyAdmin кажется самым простым решением. Если же это шаг по обслуживанию, который нужно выполнять программно/периодически, то этот вариант не подойдет.

jdm2112 jdm2112
13 нояб. 2015 г. 23:53:56

К сожалению, это нужно делать регулярно, без ручного доступа к базе данных.

Marcus McLean Marcus McLean
14 нояб. 2015 г. 00:03:30

Понял. В таком случае рекомендую использовать класс wpdb. Это предпочтительный метод и "способ WordPress" для прямой работы с БД. Дайте знать, если понадобится помощь с запросом. Я могу позже привести полный ответ, если нужно https://codex.wordpress.org/Class_Reference/wpdb

jdm2112 jdm2112
14 нояб. 2015 г. 00:14:04

Сколько записей вам нужно удалить? И как часто? Сырой SQL-запрос может быть быстрым, но если вы не будете очень и очень осторожны, вы оставите "осиротевшие" данные по всей базе данных. А WordPress хранит данные во множестве таблиц со сложными перекрестными связями.

s_ha_dum s_ha_dum
14 нояб. 2015 г. 04:41:44

Используйте 'fields' => 'ids', в get_posts, чтобы получить только ID записей. Это все, что вам нужно, и это значительно ускорит ваш запрос.

Pieter Goosen Pieter Goosen
14 нояб. 2015 г. 05:09:12

@s_ha_dum "Осиротевшие" данные — это именно то, что я пытаюсь предотвратить. Я удаляю около 5.5 тыс. записей (и добавляю около 5.5 тыс. записей, так что если у вас есть решение для этого, я весь внимание). Это операция синхронизации, которая происходит в произвольные интервалы. Может происходить раз в неделю или раз в месяц.

Marcus McLean Marcus McLean
14 нояб. 2015 г. 05:59:57

@PieterGoosen Хорошее замечание, попробую так и посмотрю, что получится. Но подозреваю, что один запрос будет гораздо эффективнее.

Marcus McLean Marcus McLean
14 нояб. 2015 г. 06:00:23

@jdm2112 Вероятно, займусь этим не раньше понедельника, но похоже, это правильный путь. Спасибо.

Marcus McLean Marcus McLean
14 нояб. 2015 г. 06:01:19

@MarcusMcLean : очевидно, вы не уловили суть ;) Данные одного поста находятся в таблице posts, таблице postmeta, таблице(ах) таксономий и, возможно, таблице options. Любой SQL-запрос для удаления этих постов будет довольно сложным. Есть большой шанс оставить данные в этих таблицах. Я бы попробовал удалять, скажем, по 50 записей с интервалом в 5 минут, используя основные функции WordPress и wp_cron()

s_ha_dum s_ha_dum
14 нояб. 2015 г. 06:08:16
Показать остальные 4 комментариев
Все ответы на вопрос 4
4
43

Вы можете удалить все записи через $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)

или используйте этот запрос, заменив {{your CPT}} на ваш тип записи (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 авг. 2017 г. 20:07:38
Комментарии

это, вероятно, сработает, но не забывайте о количестве терминов в одной из таблиц терминов. В WordPress должна быть функция для обновления этого значения.

Joel M Joel M
28 февр. 2018 г. 21:37:50

у пользователей также есть счетчики записей на экране пользователей, не уверен, сохраняются ли эти данные заранее или вычисляются при загрузке страницы.

Joel M Joel M
28 февр. 2018 г. 21:39:03

@JoelM Столбец с количеством существует в таблице базы данных wp_term_taxonomy. Похоже, что функция, которую вы ищете для обновления счетчика, это wp_update_term_count($terms, $taxonomy, false) или wp_update_term_count_now($terms, $taxonomy), определенная в wp-includes/taxonomy.php.

Ken Ken
24 июл. 2019 г. 14:46:33

безопаснее использовать команду WP CLI, проверьте другой ответ

Mladen Janjetovic Mladen Janjetovic
30 мая 2024 г. 16:07:15
2
23

Теперь это можно сделать с помощью WordPress CLI, используя команду wp post delete. После установки CLI следующая команда в терминале (выполняемая в корневой директории вашего сайта) удалит все записи типа mycustomtype:

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

Никаких сырых SQL-запросов (*фу*), никаких переживаний о таймаутах, и всё это быстро. Например, я только что удалил ~2500 записей менее чем за две минуты.

Чтобы пропустить Корзину и удалить записи полностью, используйте параметр --force

4 июн. 2020 г. 18:53:01
Комментарии

Это сработало для удаления ~12k записей. Обработал без проблем. Используйте флаг --force, если хотите пропустить "корзину" и удалить навсегда.

squarecandy squarecandy
18 сент. 2020 г. 17:09:06

bash: /usr/local/bin/wp: Argument list too long 200K записей в моем случае... Почти получилось :)

SirLouen SirLouen
1 авг. 2024 г. 15:09:06
3
14

Вы можете удалить все записи пользовательского типа поста различными способами, но здесь я покажу, как сделать это без использования SQL-запросов. В данном примере наш тип поста — product (товар)

$allposts = get_posts( array('post_type' => 'product', 'numberposts' => -1) );
foreach ($allposts as $eachpost) {
    wp_delete_post( $eachpost->ID, true ); // Удаляем пост с указанным ID, включая вложения (true)
}

Смотрите полное руководство по ссылке

2 окт. 2018 г. 20:28:36
Комментарии

Прочтите исходный вопрос еще раз: "Использование get_posts() и wp_delete_post() для каждого возвращенного поста не работает; это недостаточно быстро из-за огромного количества запросов к базе данных (ошибка таймаута)."

Вы используете именно те две функции, которые он не хочет использовать.

Mike Mike
2 нояб. 2018 г. 10:19:17

Вы абсолютно правы. Но просто для перестраховки и чтобы также удалить термины, комментарии и метаданные с обновлением счетчиков терминов — это идеальный метод. Возможно, мы можем использовать для этого cron.

pathusutariya pathusutariya
4 мар. 2021 г. 08:29:00

Если передать 'fields' => 'ids' в get_posts, то функция вернет массив ID вместо массива объектов постов, что, надеюсь, немного ускорит процесс.

Flimm Flimm
13 июл. 2022 г. 17:45:07
0

Если вы добавили префикс к типу записи CPT и таксономиям CPT, например, 'abc_мой_тип_записи' и 'abc_моя_таксономия', то удалить все из базы данных можно двумя простыми запросами:

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 мар. 2023 г. 16:30:42