3

我正在尝试使用 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.

谁能帮我理解我哪里出错了?

编辑:谢谢,我没有意识到迭代字符串会给出单个字符。添加逗号以使“文件名”成为元组并解析。

4

4 回答 4

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,而且通常来说,对数据库的短途旅行越少越好。

于 2012-11-11T19:25:17.867 回答
2

我认为您的filename变量不是元组,我认为 sqlite 将其视为字符串。要制作一个元组,不要忘记在尾随逗号:

(filename,)

请记住,构成元组的是逗号,而不是括号!

于 2012-11-11T19:25:31.447 回答
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
>>> 
于 2012-11-11T19:25:46.213 回答
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()
于 2012-11-11T19:28:23.853 回答