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.

私が間違っている場所を理解するのを手伝ってくれる人はいますか?

編集:ありがとう、文字列を反復すると個々の文字が得られることに気づきませんでした。'filename' をタプルにするカンマを追加して解決しました。

4

4 に答える 4

3

まず、一度に複数の挿入を実際に行っているわけではないため、executemany を使用する必要はありません。次に、 に変更(filename)(filename,)ます。文字列とタプルの両方が iterator プロトコルをサポートしており、カンマがなければ、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 に答える