2010-12-11 5 views
1

レコードがすでにデータベースに存在するかどうかをチェックしています(同様のタイトルで)。私はそれを2つの方法で試してみましたが、どちらもうまく動作しませ問題レコードが類似していない場合に挿入する

もっとエレガントな方法(?)を使用していないが、これにより

if mode=="update": 
    #check if book is already present in the system 
    cursor.execute('IF NOT EXISTS (SELECT * FROM book WHERE TITLE LIKE "%s") INSERT INTO book (title,author,isbn) VALUES ("%s","%s","%s") END IF;' % (title,title,author,isbn)) 
    cursor.execute('SELECT bookID FROM book WHERE TITLE LIKE "%s";' % (title)) 
    bookID = cursor.fetchall() 
    print('found the bookid %s' % (bookID)) 
    #cursor.execute('INSERT INTO choice (uid,catID,priority,bookID) VALUES ("%d","%s","%s","%s");' % ('1',cat,priority,bookID)) #commented out because above doesn't work 

を存在する場合、私は、そうでない場合にエラーが(それはあるが)、「著者」が定義されていないことを言ってクエリをEXISTS得ます。レコードのこのバージョンで

if mode=="update": 
    #check if book is already present in the system 
    cursor.execute('SELECT COUNT(*) FROM book WHERE title LIKE "%s";' % (title)) 
    anyresults = cursor.fetchall() 
    print('anyresults looks like %s' % (anyresults)) 
    if anyresults[0] == 0: # if we didn't find a bookID 
     print("I'm in the loop for adding a book") 
     cursor.execute('INSERT INTO book (title,author,isbn) VALUES ("%s","%s","%s");' % (title,author,isbn)) 
    cursor.execute('SELECT bookID FROM book WHERE TITLE LIKE "%s";' % (title)) 
    bookID = cursor.fetchall() 
    print('found the bookid %s' % (bookID)) 
    #cursor.execute('INSERT INTO choice (uid,catID,priority,bookID) VALUES ("%d","%s","%s","%s");' % ('1',cat,priority,bookID)) #commented out because above doesn't work 

のマッチングのカウント、anyresultsを使用して

あまりエレガントな方法(0L)のように見えますが、私はそれに私を取得し、それを一致させる方法を見つけることができませんタプルで"本を追加するためのループ"もしanyresults [0] == 0、0L、 '0'、 '0L' - これらのどれも私をループに入れてくれないようです。

実際には存在しないのではないかもしれないと思います。私が見つけた例は、この小さなプロジェクトの範囲にはない別々の手順です。

ADDITION: 私はunutbuのコードは素晴らしい仕事だろうと思うが、私はまだ、著者は、私は間違いなくそれを渡していた場合であっても、試みられてからINSERTを防止する未定義であると言って、このダムNameErrorを取得します

if form.has_key("title"): 
    title = form['title'].value 
    mode = "update" 
if form.has_key("author"): 
    author = form['author'].value 
    mode = "update" 
    print("I'm in here") 
if form.has_key("isbn"): 
    isbn = form['isbn'].value 
    mode = "update" 

"私はここにいる"テストステートメントは決してプリントされません。何がそこに入るのを止めるだろうか?あまりにも明白なようです - 私はインデントをチェックし続け、コマンドラインでそれをテストし、3つのパラメータすべてを明確に指定しています。

+1

SQLインジェクション、go go go! –

答えて

0

ユニークインデックスをbookに設定すると、ユニークな行を挿入するのは簡単です。例えば

mysql> ALTER IGNORE TABLE book ADD UNIQUE INDEX book_index (title,author); 

はWARNING:非固有(タイトル、著者)ペアを持つ行がある場合、すべてが、1つのそのような行が削除されます。

authorフィールドを一意にする場合は、を(author)に変更してください。

どのように大きなテーブルに応じて、これは一意である

sql='INSERT IGNORE INTO book (title,author,isbn) VALUES (%s, %s, %s)' 
cursor.execute(sql,[title,author,isbn]) 

場合は、トリプレット(title,author,isbn)が挿入され、一意のレコードを挿入するために、今...

をしばらく時間がかかることがありbookテーブル。

が一意でない場合、INSERTコマンドは無視されます。

注意:第2引数はcursor.executeです。このように引数を渡すと、SQLインジェクションを防ぐことができます。

+0

ありがとうございます - これは、私が異なる著者のものである限り、同じタイトルの複数の本を持つことができるため、これを行うよりスマートな方法です。私はまだフォームに著者が記入されていても "著者"が未定義であると言うバグが1つあります。私は2つの「if」を連続して持ち、それを第2のものの中に決して作りません。私は上記のスナップを追加しました。 – umbraphile

+0

@umbraphile:何とか 'form.has_key(" author ")'はFalseでなければなりません。 'form'はディクテーションですか? 'form'または' form.keys() 'を使って、それが持つキーを確認できますか? 'form'に' author'キーがない場合、あなたは何をしたいですか? – unutbu

+0

うん、そうだった。なぜ他のフォームの値が消えていたのか分かりましたが、現在は機能しています。再度、感謝します。 – umbraphile

0

これはあなたの疑問に答えるものではありません。なぜなら、MySQLではなくPostgreSQLのためですが、私はここで自分の道を探している人たちにそれをドロップすると思いました。 Postgresので

、彼らが存在しない場合は、バッチ挿入項目を次のことができます。

CREATE TABLE book (title TEXT, author TEXT, isbn TEXT); 

# Create a row of test data: 
INSERT INTO book (title,author,isbn) VALUES ('a', 'b', 'c'); 

# Do the real batch insert: 
INSERT INTO book 
SELECT add.* FROM (VALUES 
('a', 'b', 'c'), 
('d', 'e', 'f'), 
('g', 'h', 'i'), 
) AS add (title, author, isbn) 
LEFT JOIN book ON (book.title = add.title) 
WHERE book.title IS NULL;  

これは非常に単純です。新しい行がテーブルであるかのように選択された後、左は既存のデータと結合されます。すでに存在していない行はNULL行と結合します。すでに存在するもの(book.titleがNULLでないもの)をフィルタリングします。これは非常に高速です。大きなバッチの挿入を行うのはデータベーストランザクションが1つだけで、データベースのバックエンドではバルク結合が可能です。

ところで、実際にSQLクエリーを直接フォーマットするのをやめなければなりません。クエリ置換を使用します(例: cur.execute("SELECT * FROM table WHERE title=? and isbn=?", (title, isbn))

関連する問題