ClaudeCodeでSQLiteデータベースを扱う方法【初心者向け実践】
「ExcelやCSVではもう限界。データを増やすたびに壊れる」「複数の関係者がデータを更新するので、整合性を保ちたい」「Webアプリにデータを保存する仕組みを入れたいが、サーバー管理は無理」——そんな悩みに最もフィットするのが、軽量データベース「SQLite」です。本記事では、ClaudeCodeを使ってSQLiteを扱う方法を、テーブル作成からCRUD(登録・取得・更新・削除)、Python/Node.jsからの操作、そしてWebアプリへの組み込みまで、初心者でも迷わない順序で解説します。実際のプロンプト例とコードを多数掲載しており、手を動かしながら読み進められる構成です。
結論:SQLiteは“ファイル1個でDB”、ClaudeCodeとの相性が抜群
最初に結論をお伝えします。データ管理に少し本気を出したいなら、最初に選ぶべきデータベースはSQLite一択と言って差し支えありません。理由は3つあります。第一に、SQLiteは「ファイル1個」で完結するデータベースです。サーバー構築もインストールも不要で、Mac/Windowsともに最初から使える環境が整っています。第二に、PythonにもNode.jsにも標準的に対応するライブラリが揃っており、ClaudeCodeに「SQLiteを使って」と頼めば、テーブル設計からCRUD実装まで一気に書いてくれます。第三に、後でデータ量が増えてPostgreSQLやD1(Cloudflareの分散DB)に移行することになっても、SQL文法はほぼ共通なので、知識がそのまま生かせます。本記事では、簡単な顧客管理データベースを題材に、ClaudeCodeに指示しながらゼロからDBを構築し、最終的にWebアプリ(Next.js + Cloudflare Workers)にも組み込める形まで進めていきます。「データベースは難しそう」というイメージは、本記事を読み終える頃にはきっと消えているはずです。
h2-1. SQLiteとは何か:5分で分かる基礎
データベースには大きく分けて2タイプがあります。
サーバー型(PostgreSQL、MySQL等)
- サーバーソフトを別途インストールして起動する必要がある
- 大規模・多人数アクセス向け
ファイル型(SQLite)
- ファイル1個が丸ごとデータベース
- インストール不要、小〜中規模向け
SQLiteは、Mac/Windowsともに最初からOSに組み込まれているケースが多く、Pythonの標準ライブラリ sqlite3 でそのまま使えます。たとえば customers.db というファイルを作れば、それがデータベース本体です。バックアップしたければファイルをコピーするだけ。共有したければファイルを渡すだけ。シンプルさが最大の魅力です。
プロンプト例1:環境を確認する
私のPCでSQLiteが使えるか確認したいです。Pythonで sqlite3 のバージョンを表示するスクリプトを書いてください。
import sqlite3
print(sqlite3.sqlite_version)
print(sqlite3.version)
sqlite3 はPythonに最初から入っているので、pip install は不要です。
h2-2. テーブル設計:顧客管理DBの例
データベースを作る前に、まず「何を保存するか」を決めます。今回は社内向けの顧客管理DBを想定します。
保存したい情報
- 顧客ID(自動採番)
- 氏名
- 会社名
- メールアドレス(重複不可)
- 電話番号
- 作成日時
プロンプト例2:テーブルを設計してDDLを書いてもらう
SQLiteで顧客管理データベースを作りたいです。
- 顧客ID(自動採番、主キー)
- 氏名(必須)
- 会社名
- メールアドレス(ユニーク、必須)
- 電話番号
- 作成日時(自動)
これに対応するCREATE TABLE文を書いてください。
ClaudeCodeの回答:
CREATE TABLE IF NOT EXISTS customers (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
company TEXT,
email TEXT NOT NULL UNIQUE,
phone TEXT,
created_at TEXT NOT NULL DEFAULT (datetime('now', 'localtime'))
);
PRIMARY KEY AUTOINCREMENT は自動採番、UNIQUE は重複不可、NOT NULL は必須を意味します。datetime('now', 'localtime') で日本時間の現在時刻を自動で入れる仕掛けです。
CREATE TABLEを実行する
このSQLを実行して customers.db ファイルにテーブルを作るPythonスクリプトを書いてください。
import sqlite3
conn = sqlite3.connect("customers.db")
cur = conn.cursor()
cur.execute("""
CREATE TABLE IF NOT EXISTS customers (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
company TEXT,
email TEXT NOT NULL UNIQUE,
phone TEXT,
created_at TEXT NOT NULL DEFAULT (datetime('now', 'localtime'))
)
""")
conn.commit()
conn.close()
print("customers.db を作成しました")
実行すると、フォルダに customers.db ファイルができます。これがあなたの最初のデータベースです。
h2-3. CRUDの基本:登録・取得・更新・削除
データベース操作の基本は「CRUD」と呼ばれる4種類です。Create(登録)、Read(取得)、Update(更新)、Delete(削除)。
Create(登録)
プロンプト例3:顧客を1件追加
customers テーブルに顧客を1件追加するスクリプトを書いてください。SQLインジェクションを防ぐためにプレースホルダを使ってください。
import sqlite3
conn = sqlite3.connect("customers.db")
cur = conn.cursor()
cur.execute(
"INSERT INTO customers (name, company, email, phone) VALUES (?, ?, ?, ?)",
("山田太郎", "ACME株式会社", "yamada@example.com", "03-1234-5678"),
)
conn.commit()
print("登録ID:", cur.lastrowid)
conn.close()
? がプレースホルダです。値を直接文字列結合せず、タプルで渡すことで、SQLインジェクション攻撃を防げます。
複数件を一括登録
data = [
("佐藤花子", "B商事", "sato@example.com", "06-1111-2222"),
("鈴木一郎", "C技研", "suzuki@example.com", "045-333-4444"),
]
cur.executemany(
"INSERT INTO customers (name, company, email, phone) VALUES (?, ?, ?, ?)",
data,
)
conn.commit()
Read(取得)
プロンプト例4:全顧客を表示
customers テーブルの全レコードを取得して、見やすく表示するスクリプトを書いてください。
conn = sqlite3.connect("customers.db")
conn.row_factory = sqlite3.Row # 辞書ライクにアクセスできる
cur = conn.cursor()
for row in cur.execute("SELECT * FROM customers"):
print(f"{row['id']:3} | {row['name']:8} | {row['company'] or ''} | {row['email']}")
conn.close()
条件絞り込み
cur.execute("SELECT * FROM customers WHERE company = ?", ("ACME株式会社",))
for row in cur.fetchall():
print(row["name"], row["email"])
Update(更新)
ID=1 の顧客の電話番号を 03-9999-0000 に変更してください。
cur.execute(
"UPDATE customers SET phone = ? WHERE id = ?",
("03-9999-0000", 1),
)
conn.commit()
Delete(削除)
cur.execute("DELETE FROM customers WHERE id = ?", (3,))
conn.commit()
これだけで、CRUDのすべてをカバーできます。
h2-4. CSVからの一括インポート
実務でデータベースを作るとき、最初の壁は「既存データをどう投入するか」です。多くの場合、CSVやExcelからのインポートになります。
プロンプト例5:CSVを一括インポート
customers_initial.csv(name, company, email, phone のカラム)の中身を customers テーブルに一括登録してください。email が重複している場合はスキップしてください。
import csv
import sqlite3
conn = sqlite3.connect("customers.db")
cur = conn.cursor()
with open("customers_initial.csv", encoding="utf-8") as f:
reader = csv.DictReader(f)
for row in reader:
try:
cur.execute(
"INSERT INTO customers (name, company, email, phone) VALUES (?, ?, ?, ?)",
(row["name"], row["company"], row["email"], row["phone"]),
)
except sqlite3.IntegrityError:
print(f"スキップ(メール重複): {row['email']}")
conn.commit()
print("インポート完了")
UNIQUE 制約に違反したときに IntegrityError が出るので、それをキャッチしてスキップする実装です。
h2-5. リレーションを作る:注文テーブルの追加
実務では「顧客」だけでなく「注文」「商品」など複数のテーブルが関連し合うことが多くなります。これがリレーショナルデータベースの本領発揮どころです。
プロンプト例6:注文テーブルを設計
customers テーブルと紐づく orders テーブルを追加してください:
- 注文ID(自動採番)
- 顧客ID(customers.id を参照する外部キー)
- 商品名
- 金額
- 注文日(デフォルトで現在日時)
CREATE TABLE IF NOT EXISTS orders (
id INTEGER PRIMARY KEY AUTOINCREMENT,
customer_id INTEGER NOT NULL,
product TEXT NOT NULL,
amount INTEGER NOT NULL,
ordered_at TEXT NOT NULL DEFAULT (datetime('now', 'localtime')),
FOREIGN KEY (customer_id) REFERENCES customers(id)
);
JOINで結合表示
顧客の名前と注文情報を1つのSQLで取得し、注文がない顧客は除外して表示するクエリを書いてください。
sql = """
SELECT c.name, c.company, o.product, o.amount, o.ordered_at
FROM customers c
INNER JOIN orders o ON o.customer_id = c.id
ORDER BY o.ordered_at DESC
"""
for row in cur.execute(sql):
print(row)
JOINは慣れるまで難しく感じますが、ClaudeCodeに「顧客と注文を結合して」と日本語で伝えれば、適切なSQLを生成してくれます。
h2-6. インデックスとパフォーマンス
データ量が増えると、検索が遅くなります。これを解消するのが「インデックス」です。
プロンプト例7:インデックスを作成
customers テーブルの email カラムと、orders テーブルの customer_id カラムに、それぞれインデックスを張ってください。
CREATE INDEX IF NOT EXISTS idx_customers_email ON customers(email);
CREATE INDEX IF NOT EXISTS idx_orders_customer_id ON orders(customer_id);
これで、メールアドレスでの検索や、顧客ごとの注文取得が劇的に速くなります。
EXPLAIN QUERY PLANで実行計画を確認
for row in cur.execute("EXPLAIN QUERY PLAN SELECT * FROM customers WHERE email = ?", ("yamada@example.com",)):
print(row)
SEARCH ... USING INDEX という表示が出ればインデックスが効いている証拠です。
h2-7. Node.jsからSQLiteを操作する
Webアプリ(Next.jsなど)の裏側でSQLiteを使うなら、Node.js側からの操作も覚えておきましょう。
プロンプト例8:better-sqlite3で操作
Node.jsからSQLiteを使いたいです。better-sqlite3 を使って customers.db を読み書きするサンプルを書いてください。
// npm install better-sqlite3
import Database from "better-sqlite3";
const db = new Database("customers.db");
// 登録
const insert = db.prepare(
"INSERT INTO customers (name, company, email, phone) VALUES (?, ?, ?, ?)"
);
insert.run("田中三郎", "D工業", "tanaka@example.com", "099-555-6666");
// 取得
const all = db.prepare("SELECT * FROM customers").all();
console.log(all);
db.close();
better-sqlite3 は同期APIで、JSON的な書き味で扱えるのが特徴です。Express.jsやNext.jsのAPIルートでも使いやすい設計になっています。
h2-8. Webアプリへの組み込み:Next.js + D1への発展
社内向けのちょっとした管理ツールを「自分用のWebアプリ」として動かしたいなら、Next.js + Cloudflare Workers + D1の構成がおすすめです(社内インフラ標準としてもこれが推奨されています)。
D1とSQLiteの関係
Cloudflare D1は、SQLiteの構文をそのまま使える分散データベースサービスです。つまり、SQLiteでローカルに作ったテーブル定義(CREATE TABLE文)が、D1にもほぼそのまま流用できます。
プロンプト例9:D1への移行用SQLを生成
ローカルの customers.db のテーブル定義を、Cloudflare D1にそのまま移行するためのSQLファイル schema.sql を生成してください。
CREATE TABLE IF NOT EXISTS customers (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
company TEXT,
email TEXT NOT NULL UNIQUE,
phone TEXT,
created_at TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE TABLE IF NOT EXISTS orders (
id INTEGER PRIMARY KEY AUTOINCREMENT,
customer_id INTEGER NOT NULL,
product TEXT NOT NULL,
amount INTEGER NOT NULL,
ordered_at TEXT NOT NULL DEFAULT (datetime('now')),
FOREIGN KEY (customer_id) REFERENCES customers(id)
);
CREATE INDEX IF NOT EXISTS idx_customers_email ON customers(email);
このSQLは wrangler d1 execute <DB名> --file=schema.sql で適用できます。本番Webアプリに進む際は、認証はCloudflare Accessで特定メールアドレスに限定し、APIキーや秘密情報は必ずCloudflareのSecretsに格納してください。詳細はエンジニアと相談しながら進めるのが安全です。
実践チュートリアル:顧客管理ツールを30分で作る
ここまでの内容を踏まえた30分チュートリアルです。手元で試してみてください。
ステップ1: 作業用フォルダを作り、claude を起動。
ステップ2: 次のプロンプトを順番に投げる。
1. customers と orders の2テーブルを持つ customers.db を作成してください。スキーマはh2-2およびh2-5のとおりです。
2. サンプル顧客5名と、注文10件をダミーデータとして投入してください。
3. 顧客と注文をJOINして、「顧客名・会社名・直近の注文商品・累計金額」を一覧表示するクエリを書いてください。
4. 上記の処理をすべて1つのスクリプト manage_customers.py にまとめ、コマンドラインから「list / add / search」を選べる簡易CLIにしてください。
5. このDBスキーマをCloudflare D1にも適用できる schema.sql として書き出してください。
これだけで、自分専用の顧客管理ツールがファイル1個で動くようになります。
FAQ
Q1. SQLiteはどれくらいのデータ量まで耐えられますか?
数百万行のテーブルでも実用的に動作します。ただし、多人数が同時に書き込む用途(数十人がリアルタイムで更新するようなWebサービス)には向きません。社内ツールや個人ツールの範囲なら、まず困りません。
Q2. データベースファイルが壊れることはありますか?
不適切な強制終了(プロセスのkill -9や、書き込み中のPCシャットダウン)で破損することがあります。重要なデータは必ず定期的にファイルをコピーしてバックアップしてください。スクリプトで VACUUM を実行するとファイルを整理できます。
Q3. SQL文を一から覚える必要がありますか?
最低限「SELECT、INSERT、UPDATE、DELETE、JOIN」の5つを知っていれば十分です。ClaudeCodeに日本語で指示すれば、適切なSQLを書いてくれます。完成したSQLを読みながら覚えると、自然に身につきます。
Q4. ExcelとSQLiteの使い分けは?
(1) データが100行以下、(2) 同時編集者が1人、(3) 集計だけが目的——この3つを満たすならExcelで十分です。それ以上になると、SQLiteの方が壊れにくく、検索も速くなります。
Q5. SQLインジェクションの危険を防ぐには?
本記事で紹介しているように、必ずプレースホルダ(?)を使うことです。文字列結合でSQLを組み立てる方法は絶対に避けてください。
Q6. D1への移行は本当にそのままで済みますか?
基本的なCREATE TABLEやINSERT、SELECTはほぼそのまま動きます。ただし AUTOINCREMENT の挙動など細部の差異があるため、本番運用前に必ずテストし、不明な点はエンジニアに相談してください。
Q7. データベースの中身をExcelで確認したいです。
「DB Browser for SQLite」というフリーソフトを使うと、Excelのような感覚で中身を閲覧・編集できます。「customers.db を開いて中身を表示するスクリプトを書いて」とClaudeCodeに頼めば、CSV書き出し用のコードもすぐ作ってくれます。
まとめ
データベースは難しそうに見えて、実は「ファイル1個から始められる」非常に身近な技術です。本記事では、SQLiteを題材に、テーブル設計・CRUD・リレーション・インデックス・Node.js連携・Webアプリへの発展までを一気通貫で解説しました。ポイントは、(1)まず小さなDBファイルを作ってみる、(2)CRUDの4操作をマスターする、(3)JOINで複数テーブルを連携する、(4)インデックスでパフォーマンスを確保する——という階段を1段ずつ登ることです。ClaudeCodeに日本語で指示すれば、各ステップのコードは自動生成されます。次はぜひ、手元の業務データ(顧客リスト、商品リスト、案件管理)を1つピックアップして、SQLite化してみてください。Excelで管理していたものが「壊れにくく、速く、再利用しやすい」資産に変わります。
関連記事
- ClaudeCodeとは何か?基本の理解
- ClaudeCodeの初めての使い方
- ClaudeCodeのプロンプトのコツ
- ClaudeCodeでPythonを使う方法
- ClaudeCodeでデータ分析を行う方法
- ClaudeCodeでWeb開発を行う方法