【Python】SQLite3でデータを取得する基本:cursorループ・fetchall・fetchoneの使い分け

Python標準ライブラリの sqlite3 モジュールを使用してデータベースからデータを取得する際、いくつかの方法が存在します。ここでは、cursor オブジェクトを直接反復処理する方法、fetchall() でリストとして一括取得する方法、そして fetchone() で1行ずつ取得する方法について、実用的な商品管理システムの例を用いて解説します。

目次

実行可能なサンプルコード

以下のコードは、データベースの作成、サンプルデータの挿入、そして3つの異なるパターンでのデータ取得を一通り実行する完全なスクリプトです。そのままコピーして実行環境で動作確認が可能です。

import sqlite3
import os

# データベースファイル名
DB_FILE = "inventory_management.db"

def initialize_database():
    """検証用のデータを作成する関数"""
    # 既存のファイルがあれば削除(初期化)
    if os.path.exists(DB_FILE):
        os.remove(DB_FILE)

    with sqlite3.connect(DB_FILE) as conn:
        cursor = conn.cursor()
        
        # テーブル作成
        cursor.execute("""
            CREATE TABLE products (
                product_id INTEGER PRIMARY KEY,
                product_name TEXT,
                price INTEGER
            )
        """)
        
        # サンプルデータの挿入
        data = [
            (101, 'Mechanical Keyboard', 15000),
            (102, 'Gaming Mouse', 8000),
            (103, '27inch Monitor', 35000),
            (104, 'Webcam', 6500)
        ]
        cursor.executemany("INSERT INTO products VALUES (?, ?, ?)", data)
        conn.commit()

def main():
    # データベースの初期化
    initialize_database()

    print("=== データ取得処理の開始 ===")

    with sqlite3.connect(DB_FILE) as conn:
        cursor = conn.cursor()

        # パターン1: カーソルオブジェクトを直接ループ処理
        # メモリ効率が良く、大量のデータを処理する場合に適しています
        print("\n--- 1. Cursor Loop ---")
        cursor.execute("SELECT * FROM products")
        
        for record in cursor:
            # タプル全体と、特定のカラム(例: 商品名)へのアクセス
            print(f"Record: {record}, Item: {record[1]}")

        # パターン2: fetchall()ですべて取得
        # 結果をリストとしてメモリに展開するため、リスト操作を行いたい場合に適しています
        print("\n--- 2. fetchall() ---")
        cursor.execute("SELECT * FROM products")
        all_rows = cursor.fetchall()
        
        for row in all_rows:
            print(row)

        # パターン3: fetchone()で1行ずつ取得
        # 特定の1行だけが必要な場合や、Whileループで制御したい場合に使用します
        print("\n--- 3. fetchone() ---")
        cursor.execute("SELECT * FROM products")
        
        # 1行目を取得
        first_row = cursor.fetchone()
        print(f"1st: {first_row}")
        
        # 2行目を取得(カーソル位置が進んでいるため次の行が取得される)
        second_row = cursor.fetchone()
        print(f"2nd: {second_row}")

if __name__ == "__main__":
    main()

各取得メソッドの解説

1. カーソルオブジェクトの反復処理

cursor.execute() を実行した後、cursor オブジェクト自体を for 文で回す方法です。

  • 特徴: データを1行ずつ読み込むため、メモリ消費を抑えられます。
  • 用途: 数万行を超えるような大量のデータを順次処理する場合に推奨されます。

2. fetchall() メソッド

検索結果の全ての行をリスト形式(list of tuple)で一度に取得します。

  • 特徴: すべてのデータがメモリ上に展開されます。取得後にインデックス指定でアクセスしたり、リストの機能を使いたい場合に便利です。
  • 注意点: データ量が非常に多い場合、メモリ不足(MemoryError)の原因になる可能性があります。

3. fetchone() メソッド

検索結果から次の1行だけを取得します。実行するたびにカーソルの位置が次に進みます。データがなくなると None を返します。

  • 特徴: 必要なデータだけをピンポイントで取得できます。
  • 用途: 「IDで検索して1件だけ取得する」ようなケースや、独自のループ条件で処理を進めたい場合に使用されます。
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次