PythonでSQLiteを使う方法!データベースの基本操作を解説
生徒
「先生、Pythonでデータベースを扱うことってできるんですか?」
先生
「もちろんです!PythonにはSQLiteという軽量なデータベースが標準で使えるようになっています。インストール不要で、すぐに始められますよ。」
生徒
「データベースって何ですか?難しそうですが…」
先生
「データベースは、たくさんのデータを整理して保存しておく場所のことです。例えば、住所録のように名前や電話番号を整理して保存できます。それでは、基本的な使い方を見ていきましょう!」
1. SQLiteとは?データベースの基礎知識
SQLite(エスキューライト)は、軽量で高速なデータベース管理システムです。Pythonには標準でsqlite3モジュールが組み込まれているため、追加のインストールは不要です。
データベースとは、データを効率的に保存・管理・検索するための仕組みです。例えば、Excelのような表形式でデータを整理できると考えてください。SQLiteでは、この表のことを「テーブル」と呼びます。
SQLiteの特徴は以下の通りです:
- 軽量でシンプル:大規模なサーバーが不要
- ファイルベース:データベースが1つのファイルとして保存される
- 標準搭載:Pythonに最初から入っている
- 学習しやすい:初心者でも扱いやすい
2. データベースへの接続方法
SQLiteを使うには、まずsqlite3モジュールをインポートして、データベースファイルに接続する必要があります。接続とは、データベースを開いて操作できる状態にすることです。
以下のコードで、データベースに接続してみましょう:
import sqlite3
# データベースに接続(ファイルがなければ自動的に作成される)
connection = sqlite3.connect('sample_database.db')
print("データベースに接続しました")
# 接続を閉じる
connection.close()
print("接続を閉じました")
このコードでは、sqlite3.connect()関数を使って「sample_database.db」という名前のデータベースファイルに接続しています。指定したファイルが存在しない場合は、自動的に新しいデータベースファイルが作成されます。
作業が終わったら、close()メソッドで接続を閉じることが重要です。これは、本を読み終わったら閉じるのと同じような感覚です。
データベースに接続しました
接続を閉じました
3. テーブルの作成方法
データベースに接続したら、次はデータを保存するための「テーブル」を作成します。テーブルは、Excelのシートのようなもので、列(カラム)と行(レコード)で構成されています。
テーブルを作成するには、SQL文という特別な命令文を使います。SQL(エスキューエル)は、データベースを操作するための言語です。
import sqlite3
# データベースに接続
connection = sqlite3.connect('users_database.db')
# カーソルオブジェクトを作成
cursor = connection.cursor()
# テーブルを作成するSQL文
create_table_sql = """
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
age INTEGER,
email TEXT
)
"""
# SQL文を実行
cursor.execute(create_table_sql)
print("テーブルを作成しました")
# 変更を保存
connection.commit()
# 接続を閉じる
connection.close()
このコードでは、usersという名前のテーブルを作成しています。cursorは、データベースに対して命令を実行するための道具です。カーソルを使って、SQL文を実行します。
テーブルの各列には以下の情報を定義しています:
id:整数型で主キー(各レコードを識別するための番号)name:テキスト型で必須項目age:整数型email:テキスト型
commit()メソッドは、変更内容をデータベースに確定させるために必要です。これを実行しないと、変更が保存されません。
4. データの挿入(INSERT)
テーブルが作成できたら、次はデータを追加してみましょう。データの追加にはINSERT文を使います。これは、ノートに新しい情報を書き込むようなイメージです。
import sqlite3
connection = sqlite3.connect('users_database.db')
cursor = connection.cursor()
# データを挿入するSQL文
insert_sql = "INSERT INTO users (name, age, email) VALUES (?, ?, ?)"
# 挿入するデータ
data = ('山田太郎', 25, 'yamada@example.com')
# SQL文を実行
cursor.execute(insert_sql, data)
print("データを1件追加しました")
# 複数のデータを一度に追加
users_list = [
('佐藤花子', 30, 'sato@example.com'),
('鈴木一郎', 28, 'suzuki@example.com'),
('田中美咲', 22, 'tanaka@example.com')
]
cursor.executemany(insert_sql, users_list)
print(f"データを{len(users_list)}件追加しました")
# 変更を保存
connection.commit()
# 接続を閉じる
connection.close()
このコードでは、?をプレースホルダーとして使っています。プレースホルダーは、後から実際の値を入れるための「穴埋め問題」のようなものです。これにより、安全にデータを挿入できます。
executemany()メソッドを使えば、複数のデータを一度に追加できます。効率的にデータを登録したい場合に便利です。
5. データの取得(SELECT)
データベースに保存したデータを取り出すには、SELECT文を使います。これは、保存した情報を読み出す操作です。
import sqlite3
connection = sqlite3.connect('users_database.db')
cursor = connection.cursor()
# すべてのデータを取得
cursor.execute("SELECT * FROM users")
all_users = cursor.fetchall()
print("全ユーザー情報:")
for user in all_users:
print(f"ID: {user[0]}, 名前: {user[1]}, 年齢: {user[2]}, メール: {user[3]}")
# 特定の条件でデータを取得
cursor.execute("SELECT name, age FROM users WHERE age >= ?", (25,))
filtered_users = cursor.fetchall()
print("\n25歳以上のユーザー:")
for user in filtered_users:
print(f"名前: {user[0]}, 年齢: {user[1]}")
connection.close()
SELECT * FROM usersは、usersテーブルからすべての列のデータを取得する命令です。*は「すべて」を意味します。
fetchall()メソッドは、実行結果をすべて取得します。結果はリスト形式で返されるため、for文で1件ずつ処理できます。
WHERE句を使うことで、条件に合うデータだけを取得できます。例えば、「年齢が25歳以上」という条件を指定しています。
6. データの更新(UPDATE)
すでに登録されているデータを修正するには、UPDATE文を使います。例えば、ユーザーの年齢やメールアドレスを変更する場合に使用します。
import sqlite3
connection = sqlite3.connect('users_database.db')
cursor = connection.cursor()
# 特定のユーザーの年齢を更新
update_sql = "UPDATE users SET age = ? WHERE name = ?"
cursor.execute(update_sql, (26, '山田太郎'))
print(f"{cursor.rowcount}件のデータを更新しました")
# 変更を保存
connection.commit()
# 更新後のデータを確認
cursor.execute("SELECT * FROM users WHERE name = '山田太郎'")
updated_user = cursor.fetchone()
print(f"更新後のデータ: {updated_user}")
connection.close()
UPDATE文では、SETで変更する列と新しい値を指定し、WHEREで更新対象のレコードを指定します。WHERE句を忘れると、すべてのレコードが更新されてしまうので注意が必要です。
rowcount属性を使うと、更新されたレコードの件数を確認できます。fetchone()メソッドは、1件だけデータを取得する場合に使います。
7. データの削除(DELETE)
不要になったデータを削除するには、DELETE文を使います。ただし、削除したデータは元に戻せないため、慎重に操作する必要があります。
import sqlite3
connection = sqlite3.connect('users_database.db')
cursor = connection.cursor()
# 特定のユーザーを削除
delete_sql = "DELETE FROM users WHERE name = ?"
cursor.execute(delete_sql, ('田中美咲',))
print(f"{cursor.rowcount}件のデータを削除しました")
# 変更を保存
connection.commit()
# 削除後のデータを確認
cursor.execute("SELECT COUNT(*) FROM users")
count = cursor.fetchone()[0]
print(f"現在のユーザー数: {count}件")
connection.close()
DELETE文でもWHERE句を使って、削除対象を指定します。WHERE句を指定しないと、テーブル内のすべてのデータが削除されてしまうので十分注意してください。
COUNT(*)は、テーブル内のレコード数を数えるSQL関数です。削除後に残っているデータ件数を確認できます。
8. エラー処理とwith文の活用
データベース操作では、エラーが発生する可能性があります。安全にデータベースを扱うために、例外処理とwith文を使う方法を学びましょう。
import sqlite3
try:
# with文を使うと自動的に接続を閉じてくれる
with sqlite3.connect('users_database.db') as connection:
cursor = connection.cursor()
# データを取得
cursor.execute("SELECT * FROM users")
users = cursor.fetchall()
print(f"取得したユーザー数: {len(users)}件")
for user in users:
print(user)
# commitは自動的に実行される
except sqlite3.Error as e:
print(f"データベースエラーが発生しました: {e}")
finally:
print("データベース操作を終了しました")
with文を使うと、ブロックを抜けるときに自動的に接続を閉じてくれるため、close()を明示的に呼ぶ必要がありません。また、エラーが発生した場合も安全に処理できます。
try-except文で例外処理を行うことで、エラーが発生してもプログラムが異常終了せず、適切なメッセージを表示できます。finallyブロックは、エラーの有無に関わらず必ず実行されます。
9. 実践的な使用例:簡単な顧客管理システム
ここまで学んだ内容を組み合わせて、簡単な顧客管理システムを作ってみましょう。データの追加、表示、検索を行う実用的な例です。
import sqlite3
def create_customer_database():
with sqlite3.connect('customers.db') as conn:
cursor = conn.cursor()
cursor.execute("""
CREATE TABLE IF NOT EXISTS customers (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
phone TEXT,
address TEXT
)
""")
print("顧客データベースを作成しました")
def add_customer(name, phone, address):
with sqlite3.connect('customers.db') as conn:
cursor = conn.cursor()
cursor.execute(
"INSERT INTO customers (name, phone, address) VALUES (?, ?, ?)",
(name, phone, address)
)
print(f"顧客「{name}」を登録しました")
def show_all_customers():
with sqlite3.connect('customers.db') as conn:
cursor = conn.cursor()
cursor.execute("SELECT * FROM customers")
customers = cursor.fetchall()
print("\n=== 顧客一覧 ===")
for customer in customers:
print(f"ID: {customer[0]}, 名前: {customer[1]}, 電話: {customer[2]}, 住所: {customer[3]}")
# 実行例
create_customer_database()
add_customer('高橋健太', '090-1234-5678', '東京都渋谷区')
add_customer('伊藤あゆみ', '080-9876-5432', '大阪府大阪市')
show_all_customers()
この例では、関数を使ってデータベース操作を整理しています。AUTOINCREMENTを指定することで、IDが自動的に連番で割り当てられます。
実際のアプリケーションでは、このように機能ごとに関数を分けることで、コードが読みやすく、メンテナンスしやすくなります。
10. SQLiteを使う上での注意点とベストプラクティス
SQLiteを効果的に使うために、知っておくべき重要なポイントをまとめました。
データベース接続は必ず閉じる
データベースへの接続を開いたままにすると、リソースを無駄に消費します。with文を使うか、close()メソッドで必ず閉じましょう。
プレースホルダーを使う
SQL文に直接値を埋め込むのではなく、プレースホルダー(?)を使うことで、SQLインジェクション攻撃という危険な攻撃を防げます。
commitを忘れない
データの追加、更新、削除を行った後は、commit()メソッドで変更を確定させる必要があります。これを忘れると、変更が保存されません。
エラー処理を実装する
データベース操作では予期しないエラーが発生する可能性があります。try-except文を使って、適切なエラー処理を実装しましょう。
WHERE句を忘れない
UPDATEやDELETE文でWHERE句を指定し忘れると、すべてのデータが対象になってしまいます。特に削除操作では十分注意してください。