Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python sqlite3:两个数据库中表的差异_Python_Sqlite - Fatal编程技术网

Python sqlite3:两个数据库中表的差异

Python sqlite3:两个数据库中表的差异,python,sqlite,Python,Sqlite,我有两个具有相同模式的数据库,我希望在其中一个表上有效地进行差异。即,仅返回唯一记录,不考虑主键 columns = zip(*db1.execute("PRAGMA table_info(foo)").fetchall())[1] db1.execute("ATTACH DATABASE '/path/to/db1.db' AS db1") db1.execute("ATTACH DATABASE '/path/to/db2.db' AS db2") db2.execute("ATTACH D

我有两个具有相同模式的数据库,我希望在其中一个表上有效地进行差异。即,仅返回唯一记录,不考虑主键

columns = zip(*db1.execute("PRAGMA table_info(foo)").fetchall())[1]
db1.execute("ATTACH DATABASE '/path/to/db1.db' AS db1")
db1.execute("ATTACH DATABASE '/path/to/db2.db' AS db2")
db2.execute("ATTACH DATABASE '/path/to/db1.db' AS db1")
db2.execute("ATTACH DATABASE '/path/to/db2.db' AS db2")
data = db2.execute("""
    SELECT 
        one.* 
    FROM 
        db1.foo AS one 
        JOIN db2.foo 
        AS two 
    WHERE {}
    """.format(' AND '.join( ['one.{0}!=two.{0}'.format(c) for c in columns[1:]]))
).fetchall()
也就是说,忽略主键(在本例中为
meow
),不要返回两个数据库中相同的记录

db1
中的表
foo
如下所示:

meow    mix    please   deliver
1       123    abc
2       234    bcd      two
3       345    cde
meow    mix    please   deliver
1       345    cde
2       123    abc      one
3       234    bcd      two     
4       456    def      four
db2
中的表
foo
如下所示:

meow    mix    please   deliver
1       123    abc
2       234    bcd      two
3       345    cde
meow    mix    please   deliver
1       345    cde
2       123    abc      one
3       234    bcd      two     
4       456    def      four
因此,
db2
中的唯一条目是:

[(2, 123, 'abc', 'one'), (4, 456, 'def', 'four')]
这就是我得到的。如果我有两个以上的专栏,这将非常有效。但如果只有两个,即主键和一个值,如在查找表中:

bar  baz         bar   baz
1    123         1     234
2    234         2     345
3    345         3     123
                 4     456
我得到所有非唯一值重复N-1次,唯一值重复N次,其中N是
db1
中的记录数。我理解为什么会发生这种情况,但我不知道如何解决它

[(1, '234'),
 (1, '234'),
 (2, '345'),
 (2, '345'),
 (3, '123'),
 (3, '123'),
 (4, '456'),
 (4, '456'),
 (4, '456')]
我的一个想法是,在提取所有重复结果后,只取模量:

N = db1.execute("SELECT Count(*) FROM foo").fetchone()[0]
data = [
     list(data) 
     for data,n in itertools.groupby(sorted(data)) 
     if np.mod(len(list(n)),N)==0
]
哪种方法有效:

[[4, '456']]
但这看起来很混乱,如果可能的话,我想在第一个SQL查询中完成这一切


此外,在大型表上(我的真实数据库有大约10k条记录),这需要很长时间。有没有办法优化这个?谢谢

替换我先前的答案——这里有一个很好的通用解决方案

具有如下所示的输入表:

sqlite> select * from t1;
meow        mix         please      delivery  
----------  ----------  ----------  ----------
1           123         abc                   
2           234         bcd         two       
3           345         cde                   
select sum(q1.db), mix, please, delivery from (select 1 as db, mix, please,
delivery from t1 union all select 2 as db, mix, please, delivery from t2) q1
group by mix, please, delivery having sum(db)=2; 

sum(q1.db)  mix         please      delivery  
----------  ----------  ----------  ----------
2           123         abc         one       
2           456         def         four      

您可以获得t2/非t1中的记录(忽略主键),如下所示:

sqlite> select * from t1;
meow        mix         please      delivery  
----------  ----------  ----------  ----------
1           123         abc                   
2           234         bcd         two       
3           345         cde                   
select sum(q1.db), mix, please, delivery from (select 1 as db, mix, please,
delivery from t1 union all select 2 as db, mix, please, delivery from t2) q1
group by mix, please, delivery having sum(db)=2; 

sum(q1.db)  mix         please      delivery  
----------  ----------  ----------  ----------
2           123         abc         one       
2           456         def         four      
通过更改having子句中的值,可以执行不同的集合操作
SUM(DB)=1
返回1中的记录/不返回2中的记录
SUM(DB)=2
返回2中的记录/不返回1中的记录
SUM(DB)=1或SUM(DB)=2
返回其中一个(但不是两个)中存在的记录;和
SUM(DB)=3
返回两者中存在的记录

这对你唯一不起作用的就是返回PK。这不能在我编写的查询中完成,因为
GROUP BY
SUM
操作仅适用于公共/聚合数据,并且PK字段根据定义是唯一的。如果您知道每个数据库中非PK字段的组合是唯一的,那么您可以使用返回的记录创建一个新的查询来查找PK


注意,这种方法可以很好地扩展到两个以上的表。通过将db字段设置为2的幂,可以对任意数量的表进行操作。例如,如果您为t1设置了1个作为db,为t2设置了2个作为db,为t3设置了4个作为db,为t4设置了8个作为db,那么您可以通过更改having条件来找到所需表格的任何交叉点/差异,例如,
having SUM(db)=5
将返回t1和t3中的记录,但不在t2或t4中的记录。

它正确地获取了这些记录,但没有提取出唯一的记录。具有条件的
是否应不同?我得到
[(1,'123',abc',None),(1,'234',bcd',two'),(1,'345',cde',None),(2,'123',abc',one'),(2,'345',bcd',two'),(2,'345',cde',None),(2,'456',def',four')]
结果。同样,这应该返回
[(2,'123,'abc',one'),(4,'456 def',four'),这不应该还三张唱片吗?(1123,‘abc’、(2123,‘abc’、‘一’)和(4456,‘定义’、‘四’)?mix=123的两个记录不相同——传递值不同。(这会影响我将要发送给您的修订答案)。用Python术语来说,这是t2-t1(集合差分)还是t2^t1(对称差分)?哦,也许我不清楚。很抱歉我只想要db2.foo中没有出现在bd1.foo中的记录,而不是两个dbs中的所有唯一记录(真正的差异)--