- Day 66:SQLite × Python ― 小さくて頼れる「顧客管理CLIアプリ」を作る
- 顧客管理CLIアプリの全体像をイメージする
- データベース設計 ― customersテーブルを作る
- 顧客を追加する機能 ― INSERTをアプリの“入口”にする
- 顧客一覧を表示する機能 ― SELECTで「今の状態」を眺める
- 顧客検索機能 ― WHEREで「名前の一部から探す」
- 顧客情報の更新機能 ― UPDATEで「間違いを直す」
- 顧客削除機能 ― DELETEで「もう使わないデータを片付ける」
- メニューとメインループ ― CLIアプリとして完成させる
- Day 66のまとめ ― 「学んだピースが、ひとつの作品にまとまる」感覚
Day 66:SQLite × Python ― 小さくて頼れる「顧客管理CLIアプリ」を作る
Day 66では、ここまで学んできた SQLite と Python を組み合わせて、 実際に動く 顧客管理CLIアプリ を作っていきます。
- データベースのテーブル設計
- INSERT / SELECT / UPDATE / DELETE
- SQLiteとPythonの連携
これらをひとつの「作品」にまとめるイメージです。
「ちょっとした顧客リストを管理したい」「Excelだと心もとない」 そんなときに、自分で作ったCLIアプリが動いてくれたら、かなり嬉しいですよね。
今日は、その“最初の一歩”になるような、 シンプルだけれど実用的な顧客管理ツールを、ステップバイステップで組み立てていきます。
顧客管理CLIアプリの全体像をイメージする
どんなことができるアプリにするか
まずは、機能をシンプルに絞り込みます。
- 顧客を追加する(名前・メール・電話番号・メモ)
- 顧客一覧を表示する
- 顧客を検索する(名前の一部で検索)
- 顧客情報を更新する
- 顧客を削除する
これだけでも、立派な「顧客管理ツール」です。
操作はすべて CLI(コマンドライン) から行います。
- 起動するとメニューが表示される
- 数字を入力して操作を選ぶ
- 必要な情報を聞かれたら入力する
という、落ち着いた対話型のアプリにしていきます。
データベース設計 ― customersテーブルを作る
顧客情報に必要なカラムを決める
顧客管理なので、最低限こんな項目が欲しくなります。
id:主キー(自動採番)name:顧客名(必須)email:メールアドレス(必須・重複なしにしてもよい)phone:電話番号(任意)note:メモ(任意)
SQLiteのテーブル定義はこんな感じになります。
CREATE TABLE IF NOT EXISTS customers (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT NOT NULL UNIQUE,
phone TEXT,
note TEXT
);
Pythonでテーブルを作る関数を書く
# day66_customer_cli.py
import sqlite3
from pathlib import Path
DB_NAME = "day66_customers.db"
def get_connection() -> sqlite3.Connection:
"""
SQLiteデータベースに接続するための関数です。
ファイルがなければ新しく作られます。
"""
db_path = Path(DB_NAME)
conn = sqlite3.connect(db_path)
return conn
def init_db(conn: sqlite3.Connection) -> None:
"""
customers テーブルを作成する関数です。
すでに存在する場合は何もしません。
"""
sql = """
CREATE TABLE IF NOT EXISTS customers (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT NOT NULL UNIQUE,
phone TEXT,
note TEXT
);
"""
cur = conn.cursor()
cur.execute(sql)
conn.commit()
Pythonここまでで、「顧客情報をしまっておく箱」が準備できました。
顧客を追加する機能 ― INSERTをアプリの“入口”にする
顧客追加の関数を作る
def add_customer(conn: sqlite3.Connection, name: str, email: str, phone: str | None = None, note: str | None = None) -> None:
"""
customers テーブルに新しい顧客を追加する関数です。
1回の呼び出しで、1レコード(1人分)が追加されます。
"""
print(f"[ADD] 顧客を追加します: name={name}, email={email}, phone={phone}, note={note}")
sql = """
INSERT INTO customers (name, email, phone, note)
VALUES (?, ?, ?, ?);
"""
cur = conn.cursor()
cur.execute(sql, (name, email, phone, note))
conn.commit()
print("[ADD] 顧客の追加が完了しました。")
PythonCLIから入力を受け取る
def prompt_add_customer(conn: sqlite3.Connection) -> None:
"""
CLIから顧客情報を入力してもらい、追加するための関数です。
"""
print("=== 顧客追加 ===")
name = input("名前: ").strip()
email = input("メールアドレス: ").strip()
phone = input("電話番号(任意): ").strip()
note = input("メモ(任意): ").strip()
# 空文字の場合は None にしておくと扱いやすいです。
phone = phone or None
note = note or None
add_customer(conn, name, email, phone, note)
Pythonここでのポイントは、
input()でユーザーから情報を受け取る.strip()で前後の空白を取り除く- 任意項目は、空なら
Noneにしておく
という、CLIらしい素朴なやり取りです。
顧客一覧を表示する機能 ― SELECTで「今の状態」を眺める
全顧客を取得する関数
def list_customers(conn: sqlite3.Connection) -> list[tuple]:
"""
customers テーブルから全顧客を取得する関数です。
戻り値は、レコードごとのタプルのリストになります。
"""
sql = """
SELECT id, name, email, phone, note
FROM customers
ORDER BY id ASC;
"""
cur = conn.cursor()
cur.execute(sql)
rows = cur.fetchall()
return rows
PythonCLIで一覧を表示する
def show_customers(conn: sqlite3.Connection) -> None:
"""
顧客一覧をCLIに表示する関数です。
"""
print("=== 顧客一覧 ===")
rows = list_customers(conn)
if not rows:
print("登録されている顧客はいません。")
return
for row in rows:
customer_id, name, email, phone, note = row
print("-" * 40)
print(f"ID : {customer_id}")
print(f"名前 : {name}")
print(f"メール: {email}")
print(f"電話 : {phone or '(未登録)'}")
print(f"メモ : {note or '(なし)'}")
print("-" * 40)
Python一覧表示は、アプリの「今の状態」を確認するための大事な窓です。 ここが見やすいと、ちょっとしたツールでも「ちゃんとした感」がぐっと増します。
顧客検索機能 ― WHEREで「名前の一部から探す」
名前の部分一致検索をする
def search_customers_by_name(conn: sqlite3.Connection, keyword: str) -> list[tuple]:
"""
名前に keyword を含む顧客を検索する関数です。
部分一致検索を行います。
"""
sql = """
SELECT id, name, email, phone, note
FROM customers
WHERE name LIKE ?
ORDER BY id ASC;
"""
# LIKE 用に、%keyword% の形にします。
pattern = f"%{keyword}%"
cur = conn.cursor()
cur.execute(sql, (pattern,))
rows = cur.fetchall()
return rows
PythonCLIからキーワードを受け取る
def prompt_search_customer(conn: sqlite3.Connection) -> None:
"""
名前のキーワードを入力してもらい、検索結果を表示する関数です。
"""
print("=== 顧客検索(名前) ===")
keyword = input("検索キーワード: ").strip()
if not keyword:
print("キーワードが空です。検索を中止します。")
return
rows = search_customers_by_name(conn, keyword)
if not rows:
print("該当する顧客は見つかりませんでした。")
return
print(f"{len(rows)} 件の顧客が見つかりました。")
for row in rows:
customer_id, name, email, phone, note = row
print("-" * 40)
print(f"ID : {customer_id}")
print(f"名前 : {name}")
print(f"メール: {email}")
print(f"電話 : {phone or '(未登録)'}")
print(f"メモ : {note or '(なし)'}")
print("-" * 40)
Python検索機能が入ると、一気に「ツール感」が増します。 「名前の一部で探せる」というだけでも、使い勝手がかなり変わります。
顧客情報の更新機能 ― UPDATEで「間違いを直す」
特定IDの顧客を更新する
def update_customer(
conn: sqlite3.Connection,
customer_id: int,
name: str | None = None,
email: str | None = None,
phone: str | None = None,
note: str | None = None,
) -> None:
"""
指定した ID の顧客情報を更新する関数です。
渡された値が None の項目は更新しません。
"""
# 動的に SET 句を組み立てます。
fields = []
params: list[str | int | None] = []
if name is not None:
fields.append("name = ?")
params.append(name)
if email is not None:
fields.append("email = ?")
params.append(email)
if phone is not None:
fields.append("phone = ?")
params.append(phone)
if note is not None:
fields.append("note = ?")
params.append(note)
if not fields:
print("[UPDATE] 更新する項目がありません。")
return
set_clause = ", ".join(fields)
sql = f"""
UPDATE customers
SET {set_clause}
WHERE id = ?;
"""
params.append(customer_id)
cur = conn.cursor()
cur.execute(sql, params)
conn.commit()
print("[UPDATE] 顧客情報の更新が完了しました。")
PythonCLIで「どの項目を直すか」を聞く
def prompt_update_customer(conn: sqlite3.Connection) -> None:
"""
顧客IDを指定して、更新したい項目だけを入力してもらう関数です。
空の入力は「変更しない」とみなします。
"""
print("=== 顧客情報更新 ===")
try:
customer_id = int(input("更新したい顧客のID: ").strip())
except ValueError:
print("IDは整数で入力してください。")
return
# 現在の情報を表示しておくと親切です。
cur = conn.cursor()
cur.execute(
"SELECT id, name, email, phone, note FROM customers WHERE id = ?;",
(customer_id,),
)
row = cur.fetchone()
if row is None:
print("指定されたIDの顧客は存在しません。")
return
_, current_name, current_email, current_phone, current_note = row
print("現在の情報:")
print(f"名前 : {current_name}")
print(f"メール: {current_email}")
print(f"電話 : {current_phone or '(未登録)'}")
print(f"メモ : {current_note or '(なし)'}")
print("変更したい項目だけ、新しい値を入力してください。")
print("空のまま Enter を押すと、その項目は変更されません。")
name = input("新しい名前(未変更なら空のまま): ").strip()
email = input("新しいメール(未変更なら空のまま): ").strip()
phone = input("新しい電話(未変更なら空のまま): ").strip()
note = input("新しいメモ(未変更なら空のまま): ").strip()
name = name or None
email = email or None
phone = phone or None
note = note or None
update_customer(conn, customer_id, name, email, phone, note)
Python「間違えて登録してしまった」「メールアドレスが変わった」 そんなときに、更新機能があると安心感がぐっと増します。
顧客削除機能 ― DELETEで「もう使わないデータを片付ける」
特定IDの顧客を削除する
def delete_customer(conn: sqlite3.Connection, customer_id: int) -> None:
"""
指定した ID の顧客を削除する関数です。
"""
sql = "DELETE FROM customers WHERE id = ?;"
cur = conn.cursor()
cur.execute(sql, (customer_id,))
conn.commit()
print("[DELETE] 顧客の削除が完了しました。")
PythonCLIで削除を確認する
def prompt_delete_customer(conn: sqlite3.Connection) -> None:
"""
顧客IDを指定して削除する前に、確認を行う関数です。
"""
print("=== 顧客削除 ===")
try:
customer_id = int(input("削除したい顧客のID: ").strip())
except ValueError:
print("IDは整数で入力してください。")
return
cur = conn.cursor()
cur.execute(
"SELECT id, name, email FROM customers WHERE id = ?;",
(customer_id,),
)
row = cur.fetchone()
if row is None:
print("指定されたIDの顧客は存在しません。")
return
_, name, email = row
print(f"削除対象: ID={customer_id}, 名前={name}, メール={email}")
confirm = input("本当に削除しますか? (y/N): ").strip().lower()
if confirm == "y":
delete_customer(conn, customer_id)
else:
print("削除をキャンセルしました。")
Python削除は取り返しがつかない操作なので、 「本当に削除していいか?」 を一度確認するのが、優しさでもあり安全性でもあります。
メニューとメインループ ― CLIアプリとして完成させる
メニュー表示関数
def print_menu() -> None:
"""
顧客管理CLIアプリのメニューを表示する関数です。
"""
print("\n=== 顧客管理CLIメニュー ===")
print("1. 顧客追加")
print("2. 顧客一覧表示")
print("3. 顧客検索(名前)")
print("4. 顧客情報更新")
print("5. 顧客削除")
print("0. 終了")
Pythonメイン関数でループを回す
def main() -> None:
"""
顧客管理CLIアプリのエントリポイントです。
メニューを表示し、ユーザーの選択に応じて処理を呼び分けます。
"""
conn = get_connection()
init_db(conn)
print("顧客管理CLIアプリを起動しました。")
while True:
print_menu()
choice = input("番号を選んでください: ").strip()
if choice == "1":
prompt_add_customer(conn)
elif choice == "2":
show_customers(conn)
elif choice == "3":
prompt_search_customer(conn)
elif choice == "4":
prompt_update_customer(conn)
elif choice == "5":
prompt_delete_customer(conn)
elif choice == "0":
print("アプリを終了します。")
break
else:
print("不正な入力です。0〜5の番号を選んでください。")
conn.close()
if __name__ == "__main__":
main()
Pythonこれで、ひとつのファイル day66_customer_cli.py を実行すると、
- データベースが初期化され
- メニューが表示され
- 顧客の追加・一覧・検索・更新・削除ができる
という、小さくて頼れる顧客管理CLIアプリ が完成します。
Day 66のまとめ ― 「学んだピースが、ひとつの作品にまとまる」感覚
今日のテーマは、
- SQLiteでテーブルを設計する
- Pythonから接続して、INSERT / SELECT / UPDATE / DELETE を行う
- CLIでユーザーと対話しながら、顧客情報を管理する
という、これまで学んできた要素を「ひとつのアプリ」にまとめることでした。
コードの量は少し増えましたが、 やっていることは、Day 61〜65で触れてきた内容の組み合わせです。
- テーブル設計(主キー・UNIQUE・NOT NULL)
- SELECT / WHERE / ORDER BY
- INSERT / UPDATE / DELETE
- プレースホルダで安全に値を渡す
- CLIで
input()を使って対話する
それぞれのピースが、 「顧客管理CLIアプリ」という具体的な形 に収まったことで、 「自分でもこういうツールが作れるんだ」という実感が、少しずつ湧いてきているはずです。
