85

MySQLdb モジュールを使用してデータベースに情報を挿入するのに苦労しています。テーブルに 6 つの変数を挿入する必要があります。

cursor.execute ("""
    INSERT INTO Songs (SongName, SongArtist, SongAlbum, SongGenre, SongLength, SongLocation)
    VALUES
        (var1, var2, var3, var4, var5, var6)

""")

誰かがここで構文を手伝ってくれますか?

4

7 に答える 7

275

入力パラメーターを正しくエスケープせず、アプリケーションを SQL インジェクションの脆弱性にさらす可能性があるため、SQL クエリに文字列補間を使用しないように注意してください。違いは些細に思えるかもしれませんが、実際には非常に大きな違いです

不正解 (セキュリティ上の問題あり)

c.execute("SELECT * FROM foo WHERE bar = %s AND baz = %s" % (param1, param2))

正しい (エスケープあり)

c.execute("SELECT * FROM foo WHERE bar = %s AND baz = %s", (param1, param2))

SQL ステートメントでパラメーターをバインドするために使用される修飾子が異なる DB API 実装間で異なること、および mysql クライアント ライブラリprintfが、より一般的に受け入れられている '?' の代わりにスタイル構文を使用することは、混乱を助長します。マーカー (たとえば で使用python-sqlite)。

于 2009-04-22T01:35:26.493 に答える
57

いくつかのオプションを利用できます。Python の文字列反復に慣れる必要があります。このようなことを知りたいときに、将来的に検索して成功する可能性のある用語です。

クエリに適しています:

some_dictionary_with_the_data = {
    'name': 'awesome song',
    'artist': 'some band',
    etc...
}
cursor.execute ("""
            INSERT INTO Songs (SongName, SongArtist, SongAlbum, SongGenre, SongLength, SongLocation)
            VALUES
                (%(name)s, %(artist)s, %(album)s, %(genre)s, %(length)s, %(location)s)

        """, some_dictionary_with_the_data)

おそらくすべてのデータがオブジェクトまたはディクショナリにすでにあることを考えると、2 番目の形式の方が適しています。また、年に戻ってこのメソッドを更新する必要があるときに、文字列内の「%s」の出現をカウントする必要があるのも面倒です:)

于 2009-04-22T01:04:31.387 に答える
15

リンクされたドキュメントは、次の例を示しています。

   cursor.execute ("""
         UPDATE animal SET name = %s
         WHERE name = %s
       """, ("snake", "turtle"))
   print "Number of rows updated: %d" % cursor.rowcount

したがって、これを独自のコードに適応させる必要があります-例:

cursor.execute ("""
            INSERT INTO Songs (SongName, SongArtist, SongAlbum, SongGenre, SongLength, SongLocation)
            VALUES
                (%s, %s, %s, %s, %s, %s)

        """, (var1, var2, var3, var4, var5, var6))

(SongLength が数値の場合、%s の代わりに %d を使用する必要がある場合があります)。

于 2009-04-22T00:53:31.710 に答える
7

実際、変数(SongLength)が数値であっても、パラメーターを正しくバインドするには、%sでフォーマットする必要があります。%dを使用しようとすると、エラーが発生します。このリンクからの小さな抜粋ですhttp://mysql-python.sourceforge.net/MySQLdb.html

クエリを実行するには、最初にカーソルが必要です。次に、カーソルに対してクエリを実行できます。

c=db.cursor()
max_price=5
c.execute("""SELECT spam, eggs, sausage FROM breakfast
          WHERE price < %s""", (max_price,))

この例では、max_price = 5では、なぜ文字列に%sを使用するのでしょうか。MySQLdbはそれを文字列「5」であるSQLリテラル値に変換するためです。終了すると、クエリは実際には「... WHEREprice<5」と表示されます。

于 2011-03-27T09:31:30.457 に答える
7

選択した回答の代わりとして、Marcel と同じ安全なセマンティクスを使用して、Python 辞書を使用して値を指定するコンパクトな方法を次に示します。挿入する列を追加または削除するときに簡単に変更できるという利点があります。

  meta_cols = ('SongName','SongArtist','SongAlbum','SongGenre')
  insert = 'insert into Songs ({0}) values ({1})'.format(
      ','.join(meta_cols), ','.join( ['%s']*len(meta_cols)))
  args = [ meta[i] for i in meta_cols ]
  cursor = db.cursor()
  cursor.execute(insert,args)
  db.commit()

metaは、挿入する値を保持する辞書です更新は同じ方法で行うことができます:

  meta_cols = ('SongName','SongArtist','SongAlbum','SongGenre')
  update='update Songs set {0} where id=%s'.
        .format(','.join([ '{0}=%s'.format(c) for c in meta_cols ]))
  args = [ meta[i] for i in meta_cols ]
  args.append(songid)
  cursor=db.cursor()
  cursor.execute(update,args)
  db.commit()
于 2013-04-12T20:28:19.750 に答える
0

これを行う別の方法があります。これは、MySQL の公式 Web サイトに記載されています。 https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursor-execute.html

精神的には、@Trey Stoutの回答と同じメカニズムを使用しています。しかし、私はこちらの方がきれいで読みやすいと思います。

insert_stmt = (
  "INSERT INTO employees (emp_no, first_name, last_name, hire_date) "
  "VALUES (%s, %s, %s, %s)"
)
data = (2, 'Jane', 'Doe', datetime.date(2012, 3, 23))
cursor.execute(insert_stmt, data)

そして、変数の必要性をよりよく説明するために:

注意: エスケープが行われていることに注意してください。

employee_id = 2
first_name = "Jane"
last_name = "Doe"

insert_stmt = (
  "INSERT INTO employees (emp_no, first_name, last_name, hire_date) "
  "VALUES (%s, %s, %s, %s)"
)
data = (employee_id, conn.escape_string(first_name), conn.escape_string(last_name), datetime.date(2012, 3, 23))
cursor.execute(insert_stmt, data)
于 2018-02-01T00:04:21.277 に答える