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 |
notnull | NOT 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
- データベース全体の構造把握
- マイグレーションやドキュメント作成
コメント