删除除了我在Python列表中的ID以外的所有记录

3 投票
4 回答
3857 浏览
提问于 2025-04-15 22:39

我想在一个mysql数据库中删除所有记录,但保留我列表中的记录ID。这个列表的长度可能会变化,甚至可能包含2000个以上的ID,...

目前,我把我的列表转换成一个字符串,这样就可以用类似下面的方式:
cursor.execute("""delete from table where id not in (%s)""",(list))
这样做让我感觉不太对,而且我也不知道这个列表的长度限制是多少,...

从Python中,有什么更有效的方法来做到这一点吗?

如果能在表结构中增加一个额外的字段来标记要删除的记录,那当然很好,但这不是一个选项。
如果有一个专门的表来存储这些ID,那通过SQL查询来处理就会很方便……但我真的希望能避免这些选项,如果可能的话。

谢谢,

4 个回答

0

我会在表里加一个叫“todelete”的列,类型是tinyint(1),并且设置为不允许为空,默认值为1。然后,把那些需要保留的记录的这个列更新为0。接着,执行 delete from table where todelete; 这个命令。这样做比用“not in”要快。

或者,你可以创建一个和你现在的表结构一样的新表,把需要保留的记录插入到新表里,然后把表的名字换一下。最后,删除旧的表。

1

你有没有考虑过直接在SQL里进行计算呢?如果考虑过了,那我觉得除了你现在的做法,可能没有其他办法了。当然,要确保你写的SQL是有效的,如果你直接把下面的内容放进去:

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

那肯定是有效的。我不太确定在NOT IN (...)这个部分,id的数量有没有限制,但我觉得应该是没有的,因为在使用子查询填充这个列表时,你可以用任意长的列表。

4

如果数据库表不太大,可以把所有的ID都读出来,然后列出你想删除的那些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)

如果数据库表非常大,那就需要重新创建这个表:

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')

撰写回答