PythonでSQLのプレースホルダーを使ったパラメータ化クエリを完全解説!初心者でも安全にデータベース操作
生徒
「PythonでSQLを使うとき、文字をつなげてSQL文を作っても大丈夫なんですか?」
先生
「見た目は動きますが、とても危険です。そこで使うのがプレースホルダーを使ったパラメータ化クエリです。」
生徒
「プレースホルダーって何ですか?難しそうです……」
先生
「大丈夫です。空欄を用意して、あとから安全に値を入れる仕組みだと思ってください。」
1. PythonでSQLを使うとは?
Pythonでは、データベースと呼ばれる「大量のデータを整理して保存する箱」を操作できます。SQLは、その箱に対して「データを入れて」「取り出して」「更新して」とお願いするための言葉です。PythonにはSQLiteなどのデータベースを簡単に操作できる仕組みが用意されており、アプリ開発や業務システムでよく使われます。
2. 文字列連結でSQLを書く危険性
初心者の方が最初にやりがちなのが、SQL文を文字列としてつなげる方法です。一見すると簡単ですが、入力内容によっては意図しないSQLが実行されてしまう可能性があります。これをSQLインジェクションと呼び、データが盗まれたり消されたりする原因になります。
user_id = "1"
sql = "SELECT * FROM users WHERE id = " + user_id
3. プレースホルダーとは何か
プレースホルダーとは、SQL文の中に用意する「あとで値を入れるための空欄」です。Pythonでは「?」を使うのが一般的です。先にSQLの形だけ決めておき、実際の値は別で渡します。これにより、危険な文字が自動的に処理され、安全に実行されます。
4. SQLiteでの基本的な使い方
ここではPython標準のsqlite3を使った例を見てみましょう。データベースに接続し、プレースホルダー付きのSQLを実行します。
import sqlite3
conn = sqlite3.connect("sample.db")
cursor = conn.cursor()
user_id = 1
cursor.execute(
"SELECT * FROM users WHERE id = ?",
(user_id,)
)
rows = cursor.fetchall()
5. なぜ安全になるのか
プレースホルダーを使うと、SQL文と値が完全に分離されます。たとえ値の中にSQLの命令っぽい文字が入っていても、ただのデータとして扱われます。包丁を直接渡すのではなく、ケースに入れて渡すようなイメージです。
6. INSERT文でのプレースホルダー
データを追加する場合も考え方は同じです。名前や年齢を安全にデータベースへ保存できます。
name = "山田"
age = 20
cursor.execute(
"INSERT INTO users (name, age) VALUES (?, ?)",
(name, age)
)
conn.commit()
7. UPDATE文での使い方
更新処理でもプレースホルダーを使います。どの行を更新するか、どんな値にするかを安全に指定できます。
new_age = 21
user_id = 1
cursor.execute(
"UPDATE users SET age = ? WHERE id = ?",
(new_age, user_id)
)
conn.commit()
8. よくある間違いと注意点
値を一つだけ渡す場合でも、タプルとして指定する必要があります。末尾のカンマを忘れるとエラーになるため注意しましょう。また、プレースホルダーの数と値の数は必ず一致させてください。
cursor.execute(
"SELECT * FROM users WHERE name = ?",
("山田",)
)