我正在尝试使用Python使用目录中的文件名列表填充sqlite3数据库。我不确定为什么这不起作用:
conn = sqlite3.connect( "databasefile.db" )
cur = conn.cursor()
cur.execute('CREATE TABLE IF NOT EXISTS filenames (filename TEXT)')
for root, dirnames, filenames in os.walk(directory):
for filename in filenames:
if filename.endswith(".ext"):
cur.executemany('INSERT INTO filenames (filename) VALUES (?)', (filename))
conn.commit()
我希望它在数据库文件中生成:
Column
1 1st.ext
2 2nd.ext
3 3rd.ext
但它导致了这个:
Column
1 1
2 r
3 s
4 t
5 .
6 e
7 x
8 t
9 2
10 n
11 d
12 .
etc.
有谁可以帮我理解我哪里出错了?
编辑:谢谢,我没有意识到迭代字符串会给出个别字符。添加了逗号以使'filename'成为元组并解决。
答案 0 :(得分:3)
首先,您不需要使用executemany,因为您实际上并不是一次只执行多个插入。其次,将(filename)
更改为(filename,)
。字符串和元组都支持迭代器协议,如果没有逗号,executemany函数会将变量filename
解释为迭代的东西。当您遍历字符串时,您将获得单个字符。
您可能做的另一件事情如下:
for root, dirnames, filenames in os.walk(directory):
cur.executemany("INSERT INTO filenames (filename) VALUES (?)",
[(filename,) for filename in filenames if filename.endswith(".ext")])
conn.commit()
现在你实际上正在利用executemany,一般来说,更少的短途旅行更好。
答案 1 :(得分:2)
我认为你的filename
变量不是元组,我认为sqlite认为它是一个字符串。要做一个元组,不要忘记使用尾随昏迷:
(filename,)
请记住,它是逗号,它构成一个元组,而不是括号!
答案 2 :(得分:1)
尝试:
if filename.endswith(".ext"):
cur.executemany('INSERT INTO filenames (filename) VALUES (?)', filename)
你的问题肯定是你在某个地方迭代字符串。
在普通的python IDE中,您可以按如下方式复制它:
>>> s = "my string"
>>> for x in s: print x
...
m
y
s
t
r
i
n
g
>>>
答案 3 :(得分:1)
我相信这是因为executemany
期望项目的列表能够执行。在您的脚本中,您有以下行:
cur.executemany('INSERT INTO filenames (filename) VALUES (?)', (filename))
这简化为:
cur.executemany('INSERT INTO filenames (filename) VALUES (?)', filename)
然后executemany
将您的文件名解释为单个字符列表。
要解决此问题,您可以将表达式转换为元组:
cur.executemany('INSERT INTO filenames (filename) VALUES (?)', (filename,))
...或者只是一次完成所有操作:
conn = sqlite3.connect( "databasefile.db" )
cur = conn.cursor()
cur.execute('CREATE TABLE IF NOT EXISTS filenames (filename TEXT)')
for root, dirnames, filenames in os.walk(directory):
allowedFilenames = [f for f in filenames if f.endswith(".ext")]
cur.executemany('INSERT INTO filenames (filename) VALUES (?)', allowedFilenames)
conn.commit()