将Python列表与SQLite表进行比较并获得差异

时间:2014-07-30 18:29:57

标签: python sqlite

是否有一个基于SQL查询的解决方案来比较Python列表和SQLite表,并获取那些表中没有的项目?

我将项目存储在我的SQLite表中,并且当我的代码运行时,我想只存储那些新的项目,并希望扩展我的表格。

我知道将SQL结果作为列表与我的Python列表进行比较会很容易,但我不想将查询结果加载到内存,因为我的表包含大量数据,而且我有更多的实例我的代码同时运行。

1 个答案:

答案 0 :(得分:7)

是的,你可以这样做......但我认为你不想这样做。你的目标是只插入表中没有的项目,对吧?所以:

CREATE TABLE Breakfast (id INTEGER PRIMARY KEY AUTOINCREMENT, dish UNIQUE)
INSERT INTO Breakfast (dish) VALUES ('spam')
INSERT INTO Breakfast (dish) VALUES ('eggs')

现在,在Python中,打开此数据库,然后:

>>> breakfast = ['spam', 'eggs', 'baked beans']
>>> db.execute('SELECT * FROM Breakfast').fetchall()
[(1, 'spam'), (2, 'eggs')]
>>> db.executemany('INSERT OR IGNORE INTO Breakfast (dish) VALUES(?)',
                   [[dish] for dish in breakfast])
>>> db.execute('SELECT * FROM Breakfast').fetchall()
[(1, 'spam'), (2, 'eggs'), (5, 'baked beans')]

正如您所看到的,它为'baked beans'插入了一个新行,同时保留了两个现有行,因为它们已经存在。

有关冲突条款的工作原理,请参阅ON CONFLICT文档。 (即使OR IGNORE没有拼写ON CONFLICT,它也是一个冲突条款。)


请注意,这需要一个可以在第一个位置触发冲突的约束 - 在我的示例中,它是UNIQUE列上的dish。如果你没有这样的约束,你必须手动重现相同的效果(例如,使用可怕的,丑陋的子SELECT)。但几乎总是,正确的答案是添加约束。您的问题陈述隐含地假定该值是键或其他唯一的,或者表中没有的"项"真的没有任何意义,所以你的数据模型应该反映出来。