删除除python列表中的id之外的所有记录

时间:2010-05-13 11:37:06

标签: python mysql

我想删除mysql数据库中的所有记录,但列表中的记录ID除外。该列表的长度可以变化,并且可以容易地包含2000+ id,...

目前我将我的列表转换为字符串,因此它适用于以下内容: cursor.execute(“”“从表中删除,其中id不在(%s)”“”,(列表)) 哪种感觉不对,我不知道列表有多长,....

从python中执行此操作的最有效方法是什么?

使用额外字段更改表的结构以标记/取消标记要删除的记录将是很好的但不是一个选项。 有一个存储id的专用表确实会有用,那么这可以通过sql查询来完成......但是如果可能的话我真的想避免这些选项。

谢谢,

4 个答案:

答案 0 :(得分:3)

如果db表不是太大,只需读入所有ID,然后 列出您要删除的内容:

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)

如果db表很大,则重新创建表:

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 :(得分:1)

您是否已经厌倦了直接在SQL中进行计算的可能性?如果是这样,我没有看到另一种方法,没有做你已经做的事情。当然,请确保您正在创建有效的SQL,如果您正在插入它:

','.join(str(int(x)) for x in ids)
如果在你的陈述中直接替换,你肯定是。我不确定NOT IN(...)子句中的id数量是否有限制,但会怀疑它,因为在使用子查询填充该列表时可以使用任意长的列表。

答案 2 :(得分:0)

我会向表中添加一个“todelete tinyint(1)not null default 1”列,将那些必须保存的id更新为0,然后delete from table where todelete;。它比没有快。

或者,创建一个与您的结构相同的表,在那里插入保留的行并重命名表。然后,放弃旧的。

答案 3 :(得分:-2)

这就是temporary tables的用途。您创建一个包含排除列表的临时表,并使用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中攻击它只是因为我有一个很大的词汇表方便。代码很无聊,所以没有发布。