2017-10-21 91 views
0

我是Python新手。我试图比较具有相同模式的两个sqlite数据库。表格结构在两个数据库中也是相同的,但数据不同。我想拾取两个表中从两个数据库中不存在在任一db1.fdetaildb2.fdetail使用Python比较两个sqlite数据库

DB1 -

Table - fdetail

id name key 
1  A  k1 
2  B  K2 
3  C  K3 

DB2 -

Table - fdetail

id name keyid 
1  A  k1 
2  D  K4 
3  E  K5 
4  F  K6 

期望输出

id name keyid 
1  B  k2 
2  C  K3 
3  D  K4 
4  E  K5 
5  F  K6 

我的代码是

import sqlite3 

db1 = r"C:\Users\X\Documents\sqlitedb\db1.db" 
db2 = r"C:\Users\X\Documents\sqlitedb\db2.db" 

tblCmp = "SELECT * FROM fdetail order by id" 

conn1 = sqlite3.connect(db1) 
conn2 = sqlite3.connect(db2) 

cursor1 = conn1.cursor() 
result1 = cursor1.execute(tblCmp) 
res1 = result1.fetchall() 

cursor2 = conn2.cursor() 
result2 = cursor2.execute(tblCmp) 
res2 = result2.fetchall() 

所以我有两个列表res1res2。如何根据列Keyid来比较列表。

任何帮助,高度赞赏。

回答

1

如果这两个数据库在同一个连接(这需要ATTACH)打开,你可以做在SQL比较:

import sqlite3 

db1 = r"C:\Users\X\Documents\sqlitedb\db1.db" 
db2 = r"C:\Users\X\Documents\sqlitedb\db2.db" 

conn = sqlite3.connect(db1) 
conn.execute("ATTACH ? AS db2", [db2]) 

res1 = conn.execute("""SELECT * FROM main.fdetail 
         WHERE keyid NOT IN 
         (SELECT keyid FROM db2.fdetail) 
        """).fetchall() 
res2 = conn.execute("""SELECT * FROM db2.fdetail 
         WHERE keyid NOT IN 
         (SELECT keyid FROM main.fdetail) 
        """).fetchall() 

您还可以通过查询与UNION ALL结合得到一个结果。

+0

Minor nit,但由于ATTACH中的文件名是字符串表达式,而不是标识符,因此您可以不使用占位符来传递它 - 与使用字符串格式相比。尽管这里几乎没有什么区别。 –

+0

非常感谢您的帮助。有效。我不明白几件事情。为什么它在第一个查询中是'main.fdetail'而不是'db1.fdetail' –

+0

@IljaEverilä我假设数据库名称不是表达式,但测试显示它实际上是。谢谢! –

0

您可以将您的列表转换为集合,并根据您的意图使用可用的集合操作。

1

可以使用蟒“设置”:

res1 = set(res1) 
res2 = set(res2) 
result = res1.symmetric_difference(res2) 

两个集合的对称差是一组其是在任一组中的一个元素,但不是在两者。

或者你可以遍历这两个列表分别检查是否存在。

+0

谢谢。是否有可能,如果keyid匹配,则不要在列表中包含该行。 –