SQLiteで列名を取得する方法|テーブル構造確認の完全ガイド

データベース・SQL

SQLiteでデータベースを操作していて、「あれ?このテーブルにはどんな列があったっけ?」と困ったことはありませんか?

特に、他の人が作ったデータベースや、しばらく触っていないテーブルを扱うとき、列名やデータ型を確認したいことがよくありますよね。

この記事では、SQLiteで列名を効率的に取得する3つの方法を、それぞれの特徴と使い分けのコツとともに詳しく解説します。

スポンサーリンク

なぜ列名の確認が重要なの?

よくある困った場面

データ分析をするとき

  • CSVファイルから取り込んだテーブルの構造がわからない
  • どの列に何のデータが入っているか忘れてしまった

プログラム開発をするとき

  • 動的にSQL文を組み立てる必要がある
  • エラーを防ぐために事前に列名を確認したい

チームでの開発

  • 他のメンバーが作ったテーブル構造を理解したい
  • データベース設計書が古くて実際の構造と違う

列名確認で得られるメリット

  • ミスの防止: 存在しない列名でエラーになることを避けられる
  • 効率アップ: 手探りでクエリを書く時間を短縮
  • 理解促進: データベース全体の構造を把握しやすくなる

方法1: PRAGMA table_infoで詳細情報を取得

基本的な使い方

SQLiteには、テーブルの詳細情報を取得する専用コマンド「PRAGMA table_info」があります。

PRAGMA table_info(テーブル名);

実際の例

-- usersテーブルの情報を取得
PRAGMA table_info(users);

取得できる情報

この命令を実行すると、次のような情報が表形式で表示されます:

項目説明
cid列のID(0から始まる連番)0, 1, 2…
name列名id, name, email
typeデータ型INTEGER, TEXT, REAL
notnullNOT NULL制約の有無0(なし), 1(あり)
dflt_valueデフォルト値NULL, ‘unknown’
pkプライマリキーかどうか0(違う), 1(そう)

実際の出力例

PRAGMA table_info(users);

結果:

cid | name       | type    | notnull | dflt_value | pk
----|------------|---------|---------|------------|----
0   | id         | INTEGER | 1       | NULL       | 1
1   | name       | TEXT    | 1       | NULL       | 0
2   | email      | TEXT    | 0       | NULL       | 0
3   | created_at | TEXT    | 0       | 'now'      | 0

メリットとデメリット

メリット

  • 列名だけでなく、データ型や制約も同時に確認できる
  • SQLiteの標準機能なので、どの環境でも使える
  • 結果がわかりやすい表形式

デメリット

  • SQLite専用コマンド(他のデータベースでは使えない)
  • プログラムから使うには少し工夫が必要

方法2: SELECT文とcursor.descriptionで動的取得

プログラム(PythonやPHPなど)からSQLiteを操作するとき、列名を動的に取得したい場合があります。

Pythonでの実装例

import sqlite3

def get_column_names(db_path, table_name):
    """テーブルの列名を取得する関数"""
    conn = sqlite3.connect(db_path)
    
    try:
        # ダミーのSELECT文を実行(データは取得しない)
        cursor = conn.execute(f'SELECT * FROM {table_name} LIMIT 0')
        
        # cursor.descriptionから列名を抽出
        column_names = [description[0] for description in cursor.description]
        
        return column_names
    
    finally:
        conn.close()

# 使用例
columns = get_column_names('example.db', 'users')
print("列名一覧:", columns)
# 結果: ['id', 'name', 'email', 'created_at']

PHPでの実装例

<?php
function getColumnNames($dbPath, $tableName) {
    $pdo = new PDO("sqlite:$dbPath");
    
    // LIMIT 0で構造だけ取得
    $stmt = $pdo->prepare("SELECT * FROM $tableName LIMIT 0");
    $stmt->execute();
    
    $columnNames = [];
    for ($i = 0; $i < $stmt->columnCount(); $i++) {
        $meta = $stmt->getColumnMeta($i);
        $columnNames[] = $meta['name'];
    }
    
    return $columnNames;
}

// 使用例
$columns = getColumnNames('example.db', 'users');
print_r($columns);
?>

この方法の特徴

メリット

  • プログラムから簡単に列名を取得できる
  • 取得した列名をそのまま別の処理で使える
  • データを実際に取得しないので高速

デメリット

  • データ型などの詳細情報は取得できない
  • 各プログラミング言語のAPIに依存する

使用場面

  • 動的にSQL文を組み立てるとき
  • ユーザーが選択した列だけでクエリを実行するとき
  • テーブル構造に依存しない汎用的な処理を作るとき

方法3: sqlite_masterテーブルでスキーマ情報を取得

SQLiteには、データベース内のすべてのオブジェクト(テーブル、インデックスなど)の情報を管理する特別なテーブル「sqlite_master」があります。

基本的な使い方

-- 特定のテーブルのCREATE文を取得
SELECT sql FROM sqlite_master 
WHERE type='table' AND name='users';

結果例:

CREATE TABLE users (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT NOT NULL,
    email TEXT,
    created_at TEXT DEFAULT 'now'
)

すべてのテーブル情報を確認

-- データベース内のすべてのテーブル一覧
SELECT name FROM sqlite_master WHERE type='table';

-- テーブル名と作成SQL文をまとめて確認
SELECT name, sql FROM sqlite_master WHERE type='table';

CREATE文から列名を抽出する方法

SQLの結果をプログラムで解析して列名を抽出することもできます:

import sqlite3
import re

def extract_columns_from_schema(db_path, table_name):
    """sqlite_masterからCREATE文を取得し、列名を抽出"""
    conn = sqlite3.connect(db_path)
    
    try:
        cursor = conn.execute(
            "SELECT sql FROM sqlite_master WHERE type='table' AND name=?", 
            (table_name,)
        )
        
        result = cursor.fetchone()
        if not result:
            return []
        
        create_sql = result[0]
        
        # 正規表現で列名を抽出(簡易版)
        pattern = r'\b(\w+)\s+(?:INTEGER|TEXT|REAL|BLOB|NUMERIC)'
        matches = re.findall(pattern, create_sql, re.IGNORECASE)
        
        return matches
    
    finally:
        conn.close()

# 使用例
columns = extract_columns_from_schema('example.db', 'users')
print("抽出された列名:", columns)

この方法の特徴

メリット

  • データベースの完全なスキーマ情報を確認できる
  • テーブル作成時の元のSQL文が確認できる
  • インデックスやトリガーなどの情報も同時に取得可能

デメリット

  • CREATE文の解析が複雑になることがある
  • 通常は他の方法の方が簡単で十分

使用場面

  • データベース設計の確認や文書化
  • マイグレーション処理の作成
  • データベース構造の詳細な分析

3つの方法の使い分け

方法簡単さ詳細さプログラム連携おすすめ場面
PRAGMA table_info⭐⭐⭐⭐⭐⭐⭐⭐手動確認、SQLツール
SELECT + description⭐⭐⭐⭐⭐プログラムでの動的処理
sqlite_master⭐⭐⭐スキーマ設計の確認

実用的な活用例

動的なCSV出力

import sqlite3
import csv

def export_table_to_csv(db_path, table_name, csv_path):
    """テーブルの内容をCSVに出力(列名も自動取得)"""
    conn = sqlite3.connect(db_path)
    
    try:
        # 列名を取得
        cursor = conn.execute(f'SELECT * FROM {table_name} LIMIT 0')
        column_names = [desc[0] for desc in cursor.description]
        
        # データを取得
        cursor = conn.execute(f'SELECT * FROM {table_name}')
        
        # CSVに書き出し
        with open(csv_path, 'w', newline='', encoding='utf-8') as csvfile:
            writer = csv.writer(csvfile)
            
            # ヘッダー行(列名)を書き込み
            writer.writerow(column_names)
            
            # データ行を書き込み
            writer.writerows(cursor.fetchall())
            
        print(f"{table_name}テーブルを{csv_path}に出力しました")
        
    finally:
        conn.close()

# 使用例
export_table_to_csv('example.db', 'users', 'users_export.csv')

テーブル構造の比較

def compare_table_structures(db_path1, db_path2, table_name):
    """2つのデータベース間でテーブル構造を比較"""
    
    def get_table_info(db_path, table_name):
        conn = sqlite3.connect(db_path)
        try:
            cursor = conn.execute(f'PRAGMA table_info({table_name})')
            return cursor.fetchall()
        finally:
            conn.close()
    
    info1 = get_table_info(db_path1, table_name)
    info2 = get_table_info(db_path2, table_name)
    
    if info1 == info2:
        print(f"{table_name}テーブルの構造は同じです")
    else:
        print(f"{table_name}テーブルの構造に違いがあります")
        print(f"DB1: {info1}")
        print(f"DB2: {info2}")

# 使用例
compare_table_structures('old_db.db', 'new_db.db', 'users')

よくある質問と解決方法

Q: テーブルが存在するかどうかを確認したい

-- テーブルの存在確認
SELECT name FROM sqlite_master 
WHERE type='table' AND name='users';

結果が返ってくればテーブルが存在、何も返ってこなければ存在しません。

Q: 列名に日本語が含まれている場合は?

SQLiteは日本語の列名もサポートしているので、同じ方法で取得できます:

-- 日本語列名のテーブル例
PRAGMA table_info(商品マスタ);

Q: ビュー(VIEW)の列名も取得できる?

はい、VIEWもテーブルと同様に取得できます:

PRAGMA table_info(sales_view);

Q: 大文字小文字は区別される?

SQLiteのテーブル名は大文字小文字を区別しません:

-- これらは同じテーブルを指す
PRAGMA table_info(Users);
PRAGMA table_info(users);
PRAGMA table_info(USERS);

まとめ

SQLiteで列名を取得する方法は、目的に応じて使い分けることが重要です。

迷ったときの選び方

手軽に確認したい → PRAGMA table_info

  • SQLツールやコマンドラインでの確認
  • 列名だけでなく制約情報も知りたい場合

プログラムで使いたい → SELECT + description

  • 動的なSQL生成
  • ユーザー操作に応じた柔軟な処理

設計確認したい → sqlite_master

  • データベース全体の構造把握
  • マイグレーションやドキュメント作成

コメント

タイトルとURLをコピーしました