【Python】SQLite3でカラム名を指定して値を取得する方法

Pythonの sqlite3 モジュールでは、デフォルトのデータ取得形式はタプル(tuple)ですが、設定を変更することで辞書のように「カラム名」を指定して値にアクセスすることが可能になります。これにより、SQLのSELECT文で取得したカラムの順序を気にする必要がなくなり、コードの可読性が大幅に向上します。

ここでは、sqlite3.Row を使用してカラム名でデータを取り出す具体的な実装方法を解説します。

目次

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

以下のコードは、図書館の蔵書管理を想定したデータベースを作成し、カラム名(titleauthor など)を指定してデータを取得する完全なスクリプトです。

import sqlite3
import os

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

def setup_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 books (
                book_id INTEGER PRIMARY KEY AUTOINCREMENT,
                title TEXT NOT NULL,
                author TEXT NOT NULL,
                published_year INTEGER
            )
        """)
        
        # データ挿入
        sample_books = [
            ('The Great Gatsby', 'F. Scott Fitzgerald', 1925),
            ('1984', 'George Orwell', 1949),
            ('To Kill a Mockingbird', 'Harper Lee', 1960),
            ('Brave New World', 'Aldous Huxley', 1932)
        ]
        cursor.executemany(
            "INSERT INTO books (title, author, published_year) VALUES (?, ?, ?)",
            sample_books
        )
        conn.commit()

def main():
    # データベースの準備
    setup_database()

    print("=== カラム名によるデータアクセス ===")

    with sqlite3.connect(DB_FILE) as conn:
        # 重要な設定: 行ファクトリにsqlite3.Rowを指定
        conn.row_factory = sqlite3.Row
        
        cursor = conn.cursor()

        # パターン1: カーソルループでのアクセス
        print("\n--- 1. Cursor Loop Access ---")
        cursor.execute("SELECT * FROM books")
        
        for row in cursor:
            # カラム名でアクセス可能
            print(f"ID: {row['book_id']} | Title: {row['title']}")

        # パターン2: fetchall()でのアクセス
        print("\n--- 2. fetchall() Access ---")
        cursor.execute("SELECT * FROM books WHERE published_year > 1940")
        rows = cursor.fetchall()
        
        for row in rows:
            # 辞書のように扱えるが、実体はsqlite3.Rowオブジェクト
            print(f"Title: {row['title']}, Author: {row['author']}")

        # パターン3: fetchone()でのアクセス
        print("\n--- 3. fetchone() Access ---")
        cursor.execute("SELECT * FROM books ORDER BY published_year DESC")
        
        # 1件目取得
        first_book = cursor.fetchone()
        if first_book:
            print(f"Latest Book: {first_book['title']} ({first_book['published_year']})")
        
        # 2件目取得
        second_book = cursor.fetchone()
        if second_book:
            print(f"Next Book: {second_book['title']} ({second_book['published_year']})")

if __name__ == "__main__":
    main()

解説:sqlite3.Row の仕組み

conn.row_factory = sqlite3.Row

通常、sqlite3 は結果を (1, 'The Great Gatsby', 'F. Scott Fitzgerald') のようなタプルで返します。しかし、コネクションオブジェクトの row_factory 属性に sqlite3.Row クラスを設定することで、返却されるオブジェクトが高機能な Row オブジェクトに変わります。

Rowオブジェクトの特徴

このオブジェクトはハイブリッドな特性を持っており、以下の両方の方法でデータにアクセスできます。

  1. インデックス番号: row[0] (従来のタプルと同様)
  2. カラム名: row['title'] (辞書のようなアクセス)
  3. 大文字・小文字の区別なし: SQLの仕様に準じ、カラム名の大文字小文字を区別せずにアクセス可能です(環境によっては区別される場合もあるため、正確なカラム名を使用することを推奨します)。

辞書型(dict)への変換

sqlite3.Row オブジェクトはそのままでは JSON シリアライズなどができません。純粋な辞書型として扱いたい場合は、以下のように変換します。

book_dict = dict(row)
print(book_dict)
# 出力例: {'book_id': 1, 'title': 'The Great Gatsby', ...}
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

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

目次