удалить все записи, кроме идентификатора, который у меня есть в списке Python - PullRequest
3 голосов
/ 13 мая 2010

Я хочу удалить все записи в базе данных mysql, кроме идентификаторов записей, которые у меня есть в списке. Длина этого списка может варьироваться и может легко содержать более 2000 идентификаторов, ...

В настоящее время я преобразовываю свой список в строку, чтобы он подходил примерно так: cursor.execute ("" "удалить из таблицы, в которой идентификатор не указан (% s)" "", (list)) Что не так, и я понятия не имею, насколько длинным может быть список ...

Какой самый эффективный способ сделать это из python?

Изменение структуры таблицы с дополнительным полем для пометки / снятия отметки записей для удаления было бы замечательно, но не вариант. Наличие выделенной таблицы, в которой хранятся идентификаторы, действительно было бы полезно, тогда это можно сделать просто с помощью SQL-запроса ... но я бы действительно хотел по возможности избежать этих опций.

Спасибо

Ответы [ 4 ]

3 голосов
/ 13 мая 2010

Если таблица БД не слишком велика, просто прочитайте все идентификаторы и составьте список тех, которые вы хотите удалить:

keep_ids=[...]
cursor.execute('SELECT id FROM table')
delete_ids=[]
for (row_id,) in cursor:
    if row_id not in keep_ids:
        delete_ids.append(row_id)
cursor.executemany('DELETE FROM table WHERE id = %s',delete_ids)

Если таблица БД огромна, воссоздайте таблицу:

keep_ids=[...]
cursor.execute('CREATE TABLE IF NOT EXISTS temp_table LIKE table')
cursor.executemany('INSERT INTO temp_table (SELECT * FROM table WHERE id = %s)',keep_ids)
cursor.execute('DROP TABLE table')
cursor.execute('ALTER TABLE temp_table RENAME table')
1 голос
/ 13 мая 2010

Вы исчерпали возможность выполнения вычислений в SQL напрямую? Если так, я не вижу другого способа сделать это, не делая то, что вы уже делаете. Конечно, убедитесь, что вы создаете допустимый SQL, который, если вы подключаете:

','.join(str(int(x)) for x in ids)

Вы, конечно, есть, если подставить в вашем заявлении напрямую. Я не уверен, есть ли ограничение на количество идентификаторов в предложении NOT IN (...), но сомневаюсь в этом, поскольку вы можете использовать произвольно длинный список при использовании подзапроса для заполнения этого списка.

0 голосов
/ 13 мая 2010

Я бы добавил в таблицу столбец "todelete tinyint (1) not null default 1", обновил бы его до 0 для тех идентификаторов, которые нужно сохранить, затем delete from table where todelete;. Это быстрее, чем нет.

Или создайте таблицу с такой же структурой, как у вас, вставьте в нее сохраненные строки и переименуйте таблицы. Затем бросьте старый.

0 голосов
/ 13 мая 2010

Вот для чего временные таблицы . Вы создаете временную таблицу, содержащую список исключений, и используете DBM, чтобы сделать выбор за вас. Простой пример:

CREATE TABLE words (id integer primary key not null, word string);
CREATE TEMPORARY TABLE exclusion (word string);
INSERT INTO words VALUES ... # 100,000 of these
INSERT INTO exclusion VALUES ... # 1000 of these
DELETE FROM words WHERE words.word NOT IN (SELECT word FROM exclusion);
# 99,000 records now in words, table exclusion evaporates when the session is over

Кто-то, кто действительно знает SQL, может улучшить мою последнюю строку. Если вы делаете выбор в области приложения, что-то не так. В MySQL есть временные таблицы, но даже если вы не сделали исключений CREATE / DROP, все равно было бы лучше, чем слишком длинный оператор.

Между прочим, я взломал это в Python только потому, что у меня был огромный удобный список слов. Код скучный, поэтому не размещен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...