2012-03-08 10 views
0

私はこのエラーに遭遇していません テキストファイルからsqliteにデータを転送するためのtkinterインターフェイスを使用して、Pythonでいくつかのコードを記述しています。Python/sqliteプログラムの潜在的なエラーを解決できません

まず、ここに関連するコードです:cur.execute( "INSERT INTO" で

def submit_data(self): 
    self.new_filename = self.file_entry.get() 
    self.new_tablename = self.table_entry.get() 
    self.new_fieldname = self.field_entry.get().split(',') 

    #print(self.new_fieldname) 
    self.create_new.destroy() 

    from sqlite3 import dbapi2 as sqlite 

    con = sqlite.connect(self.new_filename)  
    cur = con.cursor() 
    cur.execute('CREATE TABLE ' + self.new_tablename + '(id INTEGER PRIMARY KEY)') 
    for field in self.new_fieldname: 
     cur.execute('ALTER TABLE ' + self.new_tablename + ' ADD ' + field) 

    with open(self.filename, 'r', encoding='latin-1') as self.the_file:  
     status = True 
     #_keynumber=1 
     while status: 
      _row = self._next_line() 

      if _row: 
       _entry_list = _row.split(',') 
       # add space after text line comma for formatting 
       _entry_list = ', '.join(_entry_list) 
       #print(_entry_list) 

       #entries = {'row': _keynumber, 'entry': _entry_list} 
       #row_entry = "INSERT INTO " + self.new_tablename + " VALUES(" + _entry_list + ")" 
       cur.execute("INSERT INTO " + self.new_tablename + " VALUES(" + _entry_list + ")") 

       #_colrange = range(_colamount)      

       #_keynumber+=1 

      else: 
       status = False 

     con.commit() 

が...ライン(約6行まで)私はこのエラーを取得する: ** cur.execute (+ self.new_tablename + "VALUES(" + _entry_list + ")" "INSERT INTO") sqlite3.OperationalError:近い "":構文エラー**

私は多くの異なる方法で、この周りを変更したとき。私は一度、 "INSERT INTO ... VALUES ...."という文字列を変数として使用しました。

cur.execute(*variable*) 

このようにした場合、エラーは "OperationalError:near"を除いて同じでした。 "OperationalError:near" of "... and any of 'はどこにもありませんでした。

本当に混乱し、イライラしました。誰かが私のためにこれを壊す??

おかげ Fその読みは次のように設定されている

テキストファイルの行:私は.join使用している場合()配置することを考え出した

ので

ハリウッドで Aビッグスター、サンドラ・ディキンソンコンマの後のスペースは、文字列はINSERT INTOステートメントの2つのVALUESに相当します。

答えて

5

_entry_list = ', '.join(_entry_list) 

を削除し、これはあなたのクエリをパラメータ化し、自動的に_entry_list内のすべての値を引用します

cur.execute("INSERT INTO " + self.new_tablename + "(" + ",".join(self.new_fieldname) +") VALUES(" + ",".join(("?" for i in xrange(len(_entry_list)))) + ")", _entry_list) 

を使用しています。

self.new_tablenameself.new_fieldnameを手動で引用する必要があります。これは、どのSQL文でも使用する前に行う必要があります。

+0

これは正しい方法です。パラメータ化されたクエリを使用すると、SQLインジェクション攻撃からも保護されます。 [(誰かが "Robert"と入力するとどうなりますか); DROP TABLE Students; "あなたのGUIに?)](https://xkcd.com/327/) –

+0

ありがとう、それは動作するようですが、私は一種の周期的な問題に今実行しています。なぜなら私がidカラムで始まったテーブルを作成したとき、このコードは私のテーブルに3つのカラムがあると言っていたので、2つの値しか与えなかったからです。 "VALUES(?,"のようにバインディングを追加すると、あまりにも多くのバインディングがあるので、指定した値またはあまりにも多くの列に対してバインディングが多すぎます。 – Icsilk

+0

ええ、私は少し前にその行を削除しましたが、あまりにも多くの束縛を得ることができない/まだ多くの列の問題がまだ解決されています。 – Icsilk

0

文字列を引用する必要があります。書かれたよう

は、お使いのSQL文は次のとおりです。

あなたが使用する必要があります

INSERT INTO foo VALUES(Hello there, world, I am, unquoted, string, not good)

INSERT INTO foo VALUES("Hello there","world","I am","quoted","string","hooray")

+0

ああ、テキストファイルの文字列の両方の部分文字列も引用符で囲む必要がありますか?それをプログラマチックに行う最良の方法についてアドバイスしていますか?手で行うことはできません。 – Icsilk

+0

'_entry_list = '、' .join(_entry_list)'を '_entry_list = '"、 ".join(_entry_list)'に置き換えて、 '_entry_list =' "'+ _entry_list [: - 1] + _ entry_list [len(_entry_list)-1] +'" '' –

0

私はあなたが次の操作を行うお勧め:

a)の代わりに実行しますステートメント、コンソールにそれを印刷します。

cur.execute("INSERT INTO " + self.new_tablename + ...) 

へ:

print "INSERT INTO " + self.new_tablename + ... 

b)は、この変更を行った後、あなたのプログラムを実行して行を変更します。コンソールに印刷するSQL文を見てください。それらは有効なSQL文ですか? SQLiteのコマンドラインを起動し、あなたのプログラムによって生成されたステートメントをコピー/ペーストします。貼り付けステートメントを実行しようとすると、SQLiteはエラーを出しますか?

+0

ええ、私はこれをしました。そしてそれをもう一度やりました。私はそれらの部分文字列を引用する必要があります、私はちょうどそれに問題があります。そのリストを部分文字列に分割して引用する方法がわからないのですが、これは単なるこのテキストファイルに固有のコードです。私はそれがそれがリストに2または10のエントリを持っているかどうかに関係なく、任意のテキストファイルで動作するように十分抽象化されているようにしたい。 – Icsilk

関連する問題