【问题标题】:delete all records except the id I have in a python list删除除我在 python 列表中的 id 之外的所有记录
【发布时间】:2010-05-13 11:37:05
【问题描述】:

我想删除 mysql 数据库中的所有记录,但列表中的记录 ID 除外。该列表的长度可能会有所不同,并且很容易包含 2000 多个 id,...

目前我将我的列表转换为字符串,以便它适合这样的内容: cursor.execute("""从表中删除 id 不在 (%s)""",(list)) 这感觉不对,我不知道列表允许有多长,....

从 python 中最有效的方法是什么?

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

谢谢,

【问题讨论】:

标签: python mysql


【解决方案1】:

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

【讨论】:

  • 有趣的想法,我会尝试一下。
【解决方案2】:

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

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

如果直接在您的陈述中替换,您当然是。我不确定 NOT IN (...) 子句中的 id 数量是否有限制,但我会怀疑,因为在使用子查询填充该列表时可以使用任意长的列表。

【讨论】:

  • 是的,这就是我现在所做的。我想最好的解决方案是使用某种临时表或专用表。
【解决方案3】:

我会在表中添加一个“todelete tinyint(1) not null default 1”列,将那些必须保留的 id 更新为 0,然后 delete from table where todelete;。比不进去要快。

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

【讨论】:

    【解决方案4】:

    这就是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 中破解了这个,只是因为我手头有一个巨大的单词表。代码很无聊所以就不贴了。

    【讨论】:

    • 100,000+ 次插入的延迟不会比 100,000 个 id 的单个查询更糟吗?
    • 不知道,整个事情在我蹩脚的桌面上花了几秒钟,这个问题还假设数据库中已经存在表words
    猜你喜欢
    • 2011-11-06
    • 2021-08-02
    • 2022-01-01
    • 2012-10-01
    • 2010-10-09
    • 2011-08-18
    • 1970-01-01
    • 1970-01-01
    • 2011-03-30
    相关资源
    最近更新 更多