MySQLのクエリパラメータ化された
-
13-09-2019 - |
質問
私は困りの時間を利用MySQLdbモジュールを挿入する情報をデータベースです。が必要で挿入する6変数の表に示す。
cursor.execute ("""
INSERT INTO Songs (SongName, SongArtist, SongAlbum, SongGenre, SongLength, SongLocation)
VALUES
(var1, var2, var3, var4, var5, var6)
""")
で誰か助けてくれる構文です。
解決
注意の文字列補間のための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
).
他のヒント
あなたは利用できるいくつかのオプションがあります。あなたは、Pythonの文字列iterpolationと快適な取得したいでしょう。これは、あなたがこのようなものを知りたいとき、将来的に探してより多くの成功を持っているかもしれない用語である。
クエリのためのより良います:
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)
あなたはおそらくすでにオブジェクトまたは辞書ですべてのデータを持って考えると、第二のフォーマットは、より良いあなたに合うでしょう。また、それはあなたが戻ってきて、今年中にこの方法を更新しなければならないとき、文字列中に「%s」の外観をカウントする必要が吸う:)
関連ドキュメントは、次の例を与えます:
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を使用する必要があります)。
実際には、あなたの変数(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リテラル値、に変換されますので。それが終了していますと、クエリが実際に、と言うだろう」... WHERE価格<5" ます。
選択解答する代わりに、とマルセルのと同じ安全なセマンティクスを持つ、ここで値を指定するには、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_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()
ここでそれを行うための別の方法があります。これは、MySQLの公式ウェブサイト上で文書化されています。 ます。https://dev.mysql。 COM / DOC /コネクタのpython / EN /コネクタのpython-API-mysqlcursor-execute.htmlする
精神で、それは@Treyスタウトの答えの同じメカニックを使用しています。しかし、私はこの1つはきれいにし、より読みやすく見つけます。
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)
そして、より良い変数の必要性を説明する:
NB:行われているエスケープに注意してください。
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)
最初のソリューションは、うまく動作します。私はここで一つの小さなディテールを追加したいです。あなたはそれが型STRにする必要があります更新/置き換えしようとしている変数を確認してください。私のmysqlのタイプは10進数ですが、私はstrはクエリを実行できるようにするなどのパラメータ変数をしなければなりませんでした。
temp = "100"
myCursor.execute("UPDATE testDB.UPS SET netAmount = %s WHERE auditSysNum = '42452'",(temp,))
myCursor.execute(var)