PythonのSQLサンプル
[質問]
Pythonのsqlite3モジュールを利用し、次のSQLでDBのテーブルを作りました。
CREATE TABLE IF NOT EXISTS posts ( id INTEGER PRIMARY KEY AUTOINCREMENT, text TEXT NOT NULL, created_at DATETIME DEFAULT (DATETIME('now', 'localtime')) )このテーブルに対し、次の処理を行うPythonコードを教えてください。
- 新しい text を追加する。
INSERT INTO posts (text) VALUES (?)- すべてのレコードを取得する。
SELECT * FROM posts ORDER BY created_at DESC- textをキーワードで検索する。
SELECT * FROM posts WHERE text LIKE (?) ORDER BY created_at DESC- レコードを削除する。
DELETE FROM posts WHERE id = (?)[回答] Gemini
Pythonのsqlite3標準ライブラリを使って、これらの操作をまとめたサンプルコードを作成しました。
SQLiteは、接続(connect)した後に、命令を実行するためのカーソル(cursor)を取得して操作するのが基本の流れです。
SQLite操作のPythonコード例
import sqlite3
def get_connection():
# 'my_database.db' というファイル名でDBを作成/接続
return sqlite3.connect('my_database.db')
def create_table():
conn = get_connection()
cur = conn.cursor()
cur.execute("""
CREATE TABLE IF NOT EXISTS posts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
text TEXT NOT NULL,
created_at DATETIME DEFAULT (DATETIME('now', 'localtime'))
)
""")
conn.commit()
conn.close()
# 1. 新しい text を追加する
def add_post(text):
conn = get_connection()
cur = conn.cursor()
cur.execute("INSERT INTO posts (text) VALUES (?)", (text,))
conn.commit()
conn.close()
# 2. すべてのレコードを取得する
def get_all_posts():
conn = get_connection()
cur = conn.cursor()
cur.execute("SELECT * FROM posts ORDER BY created_at DESC")
rows = cur.fetchall()
conn.close()
return rows
# 3. textをキーワードで検索する
def search_posts(keyword):
conn = get_connection()
cur = conn.cursor()
# 部分一致のため、キーワードを % で囲む
query_param = f"%{keyword}%"
cur.execute("SELECT * FROM posts WHERE text LIKE (?) ORDER BY created_at DESC", (query_param,))
rows = cur.fetchall()
conn.close()
return rows
# 4. レコードを削除する
def delete_post(post_id):
conn = get_connection()
cur = conn.cursor()
cur.execute("DELETE FROM posts WHERE id = (?)", (post_id,))
conn.commit()
conn.close()
# --- 動作確認 ---
if __name__ == "__main__":
create_table()
# 追加
add_post("こんにちは、Pythonの世界!")
add_post("SQLiteはとても便利ですね。")
# 検索(「Python」を含むもの)
print("--- 検索結果 ---")
results = search_posts("Python")
for row in results:
print(row)
# 全件取得
print("\n--- 全件表示 ---")
all_posts = get_all_posts()
for row in all_posts:
print(row)
# 削除(例として最初の1件を削除)
if all_posts:
delete_post(all_posts[0][0])
print(f"\nID {all_posts[0][0]} を削除しました。")
💡 実装のポイント
- プレースホルダ (
?) の使用: SQL文の中に直接変数を書き込まず(f-stringなどを使わず)、必ず?を使って第二引数のタプルで値を渡してください。これは SQLインジェクション という攻撃を防ぐための必須の作法です。 - commit() の忘れ物に注意:
INSERTやDELETEなど、データを書き換える操作をした後はconn.commit()を呼ばないと、変更が確定されません。 - LIKE検索のワイルドカード:
LIKEを使った部分一致検索の場合、Python側でキーワードを%keyword%のように加工してから渡すとスムーズです。
次は、取得したデータを扱いやすくするために、タプルではなく辞書形式(row["text"] のようにアクセスできる形)で取得する方法を解説しましょうか?