2012-01-15 9 views
1

私はPythonでMySQLdbを使用しています。PythonでSQL文をチェックして実行する方法

sql = "insert into table VALUES (%s, %s, %s)" 
args = var1, var2, var3 
cursor.execute(sql, args) 

または::

cursor.execute("insert into table VALUES (%s, %s, %s)", var1, var2, var3) 

あるいは、この(これは間違っているかもしれない):私は、適切にSQL文を作成し、私のようなものをコーディングする必要があり、SQLインジェクション攻撃を避けるために、と言われた

header = ('id', 'first_name', 'last_name') 
values = ('12', 'bob'  , 'smith' ) 
cursor.execute("insert into table (%s) values (%s)", (header + values)) 

私はPHPでプログラミングしたとき、私は通常SQL文全体を長い文字列として保存してから文字列を実行します。 (PostgreSQLの付き)のようなものは:

$id   = db_prep_string(pg_escape_string($id  )); 
$first_name = db_prep_string(pg_escape_string($first_name)); 
$last_name = db_prep_string(pg_escape_string($last_name )); 

$query = "insert into table (id, first_name, last_name) values ($id, $first_name, $last_name)" 

$result = pg_query($con, $query); 
$retval = pg_fetch_array($result); 

db_prep_stringは、私は単純に全体のSQL文を表示する$queryをエコー可能性があり、デバッグに続いて

function db_prep_string($value) { 
    if( 
     !isset($value) || 
     (is_null($value)) || 
     preg_match('/^\s+$/', $value) || 
     ($value == '') 
    ) { 
    $value = 'null'; 
} 
else { 
    $value = "'$value'"; 
} 
    return $value; 
} 

です。私がPythonでできることと似たものはありますか?つまり、安全な SQL文を文字列として格納し、それを出力してデバッグしてから実行することはできますか?

私のような何かをしたいと思います:いない場合は

id   = prevent_sql_injection_string(id  ) 
first_name = prevent_sql_injection_string(first_name) 
last_name = prevent_sql_injection_string(last_name ) 

sql = "insert into table (id, first_name, last_name) values " 
sql += id   + ", " 
sql += first_name + ", " 
sql += last_name 

print sql #for debugging 

cursor.execute(sql)   

を、そしてどのように私はPythonで、その全体がビュー SQL文のですか?

ボーナス質問:Pythonを使用してSQL文にnull値を入力するにはどうすればよいですか?

+0

これは、「パラメータ化された」クエリまたはSQLを使用して呼び出されます。 – DOK

+0

ヌル値を入力する場合は、「なし」を使用します。 – MRAB

+0

pgsqlクエリに引数を埋め込んで、1つの大きな文字列を取得しましたか?ヤク! PHPでさえ、あなたは 'pg_query_params'を持っています。ここでは、クエリを値から分離することができます。 – ThiefMaster

答えて

3

いくつかの質問に答えてください:Python Database API specificationをご覧ください。たとえば、NULL値の場合、API仕様では次のようになります。

SQL NULL値は、入力および出力の のPython None singletonで表されます。

およびパラメータスタイルでは、仕様では、MySQLdbが使用する'format'オプションを含め、実装者に複数のオプションが用意されています。

データベースに対してMySQLdbが実行するクエリを確認したい場合は、ちょっと騙して接続literal(...)メソッドを使用してください。たとえば、次のようにdb.literal(...)メソッドは本当にのMySQLdbモジュールのクライアントが使用されることを意味しないので、生産コードでそれを入れていないが

>>> import MySQLdb 
>>> db = MySQLdb.connect(...) 
>>> print "insert into table VALUES (%s, %s, %s)" % db.literal((5, "ab'c", None)) 
insert into table VALUES (5, 'ab\\'c', NULL) 

はまた、MySQLdb documentationはパラメータについて言うためにこれを持っていることに注意してください。

パラメータプレースホルダのみが列の値を挿入するために使用することができます。テーブル名、文など、SQLの他の部分には使用できません。

したがって、挿入文のテーブルの列名にパラメータプレースホルダを使用することに注意してください。

-2

あなたがしたいコードが有効です。

def prevent_sql_injection_string(value): 
    if (value is None or str(value).strip()=''): 
     value = 'null' 
    else: 
     value = "'%s'" % str(value) 
    return value  

# convert inputs 
id   = prevent_sql_injection_string(id  ) 
first_name = prevent_sql_injection_string(first_name) 
last_name = prevent_sql_injection_string(last_name ) 

# construct query 
# Note: "some formatted string" % (value,value,value) syntax is like doing 
# printf("some formatted string",value,value,value) 
sql = "insert into table (id, first_name, last_name) values (%s, %s, %s)" 
     % (id,first_name,last_name) 

# print 
print sql 

# execute 
cursor.execute(sql) 
+0

誰もそれをするべきではありません! – ThiefMaster

+0

あなたのコードのフォーマットは間違っているようです( ':'で終わる最初の行の後ろにインデントされていないブロックはありません)。また、私はこれがどのように何かを防ぐのか見ていない。私が保護している文字列に一重引用符があるとどうなりますか?あなたがしているのは一重引用符を追加することなので、もし私の値が '' 'ならば、テーブルfooを落とすと問題は起こりませんか? –

+0

あなたがdownvoteするつもりならばどうしていいか説明してください - 私は興味があり、正直に知りたいと思うでしょう。 –

関連する問題