我有一个包含一列文件名的sqlite表。有些文件名是其他文件的副本,所以我想遍历每一行,在列中搜索类似的条目,然后将这些结果打印到控制台。
print(row[0])
表示我的findDupes
循环的前半部分工作,遍历每一行。当我创建另一个sqlite语句来查找类似的条目并打印输出时,事情变得奇怪。循环只打印第一个条目,而不是继续循环。
我不是SQL专家,所以不知道我做错了什么。任何帮助将不胜感激。谢谢!
def getFiles():
dirs = os.listdir(path)
for files in dirs:
c.execute('INSERT INTO myTable(files) VALUES(?)', (files,))
def findDupes():
row = c.execute('select files from myTable order by files')
while True:
row = c.fetchone()
if row == None:
break
c.execute('select files from myTable where files like ?',(row[0]+'%',))
dupe = c.fetchone()
print (dupe[0])
答案 0 :(得分:2)
首先,您的代码没有透露c
是什么 - 它是连接对象还是游标? (或者可以在这个对象中使用,但游标通常更可取)为什么它是全局的?
假设它是一个游标对象,那么正在发生的事情是你第一次通过循环,第二次调用c.execute会重置查询,所以第二次调用c.fetchone
时,sqlite正在寻找select files from myTable where files like ?
解决此问题的一种方法是使用多个游标;一个用于迭代文件名,另一个用于执行重复查找。
def findDupes(conn): #pass in your database connection object here
file_curs = conn.cursor()
file_curs.execute('select files from myTable order by files')
while True:
row = file_curs.fetchone()
if row == None:
break
dup_curs = conn.cursor()
dup_curs.execute('select files from myTable where files like ?',(row[0]+'%',))
dupe = dup_curs.fetchone()
print (dupe[0])
请注意,您可以完全在SQL中执行重复数据删除(请参阅示例Deleting duplicate rows from sqlite database),但如果您是SQL新手,则可能需要坚持使用上述内容。
答案 1 :(得分:1)
您的问题是,在您的循环中,您每次都会调用row = c.fetchone()
,这将从最近执行c 查询返回一行。在第二个循环中,这将是c.execute('select files from myTable where files like ?',(row[0]+'%',))
的结果,已经提取了一行(因此您真正使用当前代码将row
设置为c.execute('select files from myTable where files like ?',(row[0]+'%',))
的第二个结果,我假设可能会返回None
并打破你的循环。
试试这个:
def findDupes():
c.execute('select files from myTable order by files')
rows = c.fetchall()
for row in rows:
c.execute('select files from myTable where files like ?',(row[0]+'%',))
dupe = c.fetchone()
print (dupe[0])
答案 2 :(得分:1)
您需要更改使用c
的方式。第一次在findDupes()
中运行循环时,它会获取一行文件列表。在那之后,你已经有了c.execute()
的同类选择在循环的同一次迭代中执行。当第二次迭代发生时,第一个c.fetchone()
从你喜欢的查询中获取一行,而不是你在循环之外的原始所有逐个文件查询。
对两个查询使用不同的变量或游标。
答案 3 :(得分:0)
您可以通过让数据库服务器为您进行计数来另外解决此问题。这样你只需运行一个查询,而不是通过获取所有文件的低效方式,然后逐个检查:
def find_dupes():
rows = c.execute('SELECT files, COUNT(*) FROM myTable GROUP BY files HAVING COUNT(*) > 1')
return [row[0] for row in rows]
dupes = find_dupes()
print('\n'.join(dupes))