「Pythonで集めたデータを保存したいけど、本格的なデータベースは難しそう…」
「ちょっとしたアプリのデータ管理を手軽に始めたい」
そんなふうに感じていませんか?実は、Pythonを使えば追加のインストールなしで、驚くほど簡単にデータベースを扱えます。その秘密が、今回ご紹介する「SQLite」です。
この記事では、Pythonの標準機能だけでSQLiteを操作する方法を、基本から少し応用的な内容まで、豊富なサンプルコードと共に解説していきます。
そもそもSQLiteってどんなデータベース?
SQLite(エスキューライト)は、サーバーを必要としない、とても軽量なデータベース管理システムです。一般的なデータベース(MySQLやPostgreSQLなど)が、専門のサーバーソフトウェアとして動作するのに対し、SQLiteはアプリケーションに組み込んで利用します。
一番の特徴は、データベース全体が「単一のファイル」として保存されることです。設定ファイルなども必要なく、そのファイルをコピーするだけでデータベースのバックアップが完了します。この手軽さから、以下のような場面で広く使われています。
- Webブラウザの履歴保存
- スマートフォンのアプリデータ
- 小規模なWebアプリケーションのバックアップ
- データ分析の一時的なデータ置き場
本格的な大規模システムには向きませんが、「手軽にデータベースを導入したい」というニーズに応えてくれる、頼れる存在というわけです。Pythonでは標準でサポートされているため、私たちは何の準備もなしに、すぐに使い始められます。
PythonでSQLiteを使うメリット【他のDBとの比較】
Pythonには、さまざまなデータベースを操作するためのライブラリが存在します。その中でも、あえてSQLiteを選ぶメリットはどこにあるのでしょうか。他の代表的なデータベースと比較しながら、その利点を見ていきましょう。
最大のメリットは、やはり「手軽さ」に尽きます。Pythonに標準搭載されているsqlite3
モジュールをインポートするだけで、すぐにデータベース操作を始められます。環境構築でつまずく心配がないのは、特に初心者にとって大きな魅力です。
一方で、複数のユーザーが同時に書き込みを行うような、大規模なシステムには向いていないという側面も理解しておくことが大切です。ただし、複数のユーザーによる同時読み込みは問題なく行えます。また、WAL(Write-Ahead Logging)モードを有効にすることで、1つの書き込み処理と複数の読み込み処理を同時に実行することも可能です。それぞれの特徴を知り、目的に合ったデータベースを選べるようになりましょう。
特徴 | SQLite | MySQL | PostgreSQL |
---|---|---|---|
サーバー | 不要 | 必要 | 必要 |
設定 | 非常に簡単 | やや複雑 | やや複雑 |
Pythonからの利用 | 標準機能のみ | ライブラリの追加が必要 | ライブラリの追加が必要 |
得意な規模 | 小〜中規模、個人利用 | 中〜大規模 | 中〜大規模、複雑な処理 |
データ型 | 動的型付け(型制約が緩やか) | 厳密 | 厳密(多機能) |
ユースケース | デスクトップアプリ、スマホアプリ、小規模Webアプリ | 標準的なWebアプリケーション | 大規模、高信頼性が求められるシステム、地理情報など |
PythonでSQLiteを操作する基本の5ステップ
それでは、実際にPythonでSQLiteを操作してみましょう。データベースへの接続からデータの追加、検索、削除まで、一連の流れを5つのステップに分けて解説します。
ステップ1:データベースに接続する (connect
)
最初に、sqlite3
モジュールをインポートし、connect()
関数でデータベースファイルに接続します。ファイル名を指定すると、その名前のファイルがデータベースとして作成されます。もし既にファイルが存在すれば、そのデータベースに接続します。
import sqlite3
# test.dbという名前のデータベースに接続(ファイルがなければ新規作成)
conn = sqlite3.connect('test.db')
# データベース操作のためのカーソルを作成
cur = conn.cursor()
# ここにデータベース操作のコードを記述
# 最後に接続を閉じる
conn.close()
cursor
(カーソル)は、SQL文を実行し、その結果を操作するためのオブジェクトです。まずは「接続→カーソル取得→切断」という一連の流れを定型文として覚えてしまいましょう。
ステップ2:テーブルを作成する (execute
でCREATE TABLE)
データベースは、データを格納するための「テーブル」という表を持っています。SQLのCREATE TABLE
文を使って、テーブルを作成しましょう。今回は、商品ID(id)、商品名(name)、価格(price)を保存するproducts
テーブルを作ってみます。
# 'products'というテーブルが既に存在していれば削除
cur.execute('DROP TABLE IF EXISTS products')
# 'products'テーブルを作成
# id: 整数型、主キー
# name: テキスト型
# price: 整数型
cur.execute('''
CREATE TABLE products (
id INTEGER PRIMARY KEY,
name TEXT,
price INTEGER
)
''')
# 変更をデータベースに保存(コミット)
conn.commit()
execute()
メソッドにSQL文を文字列として渡すことで、さまざまな操作が可能です。INTEGER PRIMARY KEY
と指定したid
列は、内部的にはROWID
の別名として機能します。データを追加する際にid
を省略するかNULL
を指定すると、自動で連番が割り振られます。commit()
は、実行した操作をデータベースに確定させるための重要な命令です。
ステップ3:データを挿入する (execute
でINSERT)
テーブルができたので、次はデータを挿入します。INSERT
文を使いますが、ここで一つ重要な注意点があります。SQL文の中に直接変数を埋め込むのは、セキュリティ上のリスク(SQLインジェクション)があるため避けるべきです。
安全な方法として、SQL文の中には?
というプレースホルダを置き、execute()
の第二引数にタプルで値を渡します。
# データを1件挿入
cur.execute(
'INSERT INTO products (name, price) VALUES (?, ?)',
('りんご', 150)
)
conn.commit()
# 複数のデータをまとめて挿入
products_list = [
('ばなな', 200),
('みかん', 120)
]
cur.executemany(
'INSERT INTO products (name, price) VALUES (?, ?)',
products_list
)
conn.commit()
複数のデータを一度に挿入したい場合は、executemany()
メソッドが便利です。リスト形式でデータを渡すことで、効率的に処理を行えます。
ステップ4:データを取得・検索する (fetchone
, fetchall
)
データベースからデータを取得するにはSELECT
文を使います。取得した結果は、カーソルのfetchone()
(1件取得)やfetchall()
(全件取得)メソッドで取り出せます。
# 全てのデータを取得
cur.execute('SELECT * FROM products')
# fetchall()で結果をリストとして取得
print(cur.fetchall())
# 出力例: [(1, 'りんご', 150), (2, 'ばなな', 200), (3, 'みかん', 120)]
# 条件に合うデータを取得(価格が130円より高い商品)
cur.execute('SELECT * FROM products WHERE price > ?', (130,))
print(cur.fetchall())
# 出力例: [(1, 'りんご', 150), (2, 'ばなな', 200)]
# 1件だけ取得
cur.execute('SELECT * FROM products WHERE name = ?', ('りんご',))
print(cur.fetchone())
# 出力例: (1, 'りんご', 150)
WHERE
句を使うことで、特定の条件に一致するデータだけを絞り込んで検索できます。ここでも、条件の値はプレースホルダ?
を使って安全に渡しましょう。
ステップ5:データを更新・削除する (UPDATE
, DELETE
)
最後に、データの更新(UPDATE
)と削除(DELETE
)の方法です。WHERE
句で対象のデータを指定し、内容を変更したり、レコード自体を削除したりします。
# データの更新(りんごの価格を160円に変更)
cur.execute(
'UPDATE products SET price = ? WHERE name = ?',
(160, 'りんご')
)
conn.commit()
# データの削除(みかんのデータを削除)
cur.execute(
'DELETE FROM products WHERE name = ?',
('みかん',)
)
conn.commit()
# 結果を確認
cur.execute('SELECT * FROM products')
print(cur.fetchall())
# 出力例: [(1, 'りんご', 160), (2, 'ばなな', 200)]
UPDATE
やDELETE
は、データベースの内容を直接変更する強力な操作です。誤って大事なデータを消してしまわないよう、WHERE
句の条件指定は慎重に行いましょう。
トランザクション管理とエラーハンドリング
データベース操作では、「一連の処理をまとめて実行したい」という場面がよくあります。例えば、銀行振込のように「Aさんの残高を減らす」処理と「Bさんの残高を増やす」処理は、必ずセットで成功しなければなりません。
このような一連の処理のまとまりを「トランザクション」と呼びます。sqlite3
では、commit()
を呼び出すことでトランザクションが完了し、変更が確定します。もし途中でエラーが発生した場合は、rollback()
を呼び出すことで、トランザクション開始前の状態に戻せます。
このトランザクション管理を、より安全かつ簡潔に記述する方法としてwith
文があります。
# with文を使うと、ブロックを抜ける際に自動でcommitされる
# エラーが発生した場合は、自動でrollbackされる
try:
with conn:
conn.execute(
'INSERT INTO products (name, price) VALUES (?, ?)',
('いちご', 300)
)
except sqlite3.Error as e:
print(f"データベースエラー: {e}")
# 接続を閉じるのも忘れずに
conn.close()
with conn:
ブロック内で行われた操作は、ブロックが正常に終了すれば自動的にcommit
され、何らかのエラーで中断した場合は自動的にrollback
されます。これにより、commit()
の書き忘れや、エラー時の後処理を気にする必要がなくなり、コードが非常にすっきりとします。
もっと便利に!SQLite管理ツールと発展学習
Pythonコードからだけではなく、データベースの中身を直接見て確認したい時もありますよね。そんな時に便利なのが、「DB Browser for SQLite」のようなGUI管理ツールです。
このツールを使えば、作成したデータベースファイル(例:test.db
)を開いて、テーブルの構造や保存されているデータを表計算ソフトのように視覚的に確認・編集できます。開発中のデバッグなどで非常に役立つので、ぜひインストールしておくことをおすすめします。
また、データ分析ライブラリのPandasと組み合わせることで、SQLiteデータベースの内容を直接DataFrameとして読み込んだり、DataFrameの内容をデータベースに書き出したりすることも可能です。大量のデータを扱う分析作業などで、SQLiteは強力なパートナーになります。
参考:DB Browser for SQLite (公式サイト)
まとめ
今回は、Pythonの標準ライブラリsqlite3
を使って、データベースを操作する方法を基礎から解説しました。
- SQLiteはサーバー不要で、単一ファイルで管理できる手軽なデータベース。
- Pythonには標準で
sqlite3
モジュールが用意されており、すぐに使い始められる。 connect
,cursor
,execute
,commit
,close
が基本の流れ。?
プレースホルダを使い、SQLインジェクションを防ぐことが重要。with
文を使えば、トランザクション管理を安全かつ簡潔に記述できる。
外部ライブラリのインストールや複雑な環境構築なしに、これだけのデータベース操作が実現できるのはSQLiteの大きな魅力です。まずはこの記事のサンプルコードを手元で動かしてみて、データベース操作の第一歩を踏み出してみてください。きっとあなたのPythonプログラミングの幅が、ぐっと広がるはずです。