Apache Cassandra(以下Cassandra)は、スケーラビリティと可用性に優れた分散型NoSQLデータベースです。
本記事では、PythonからCassandraを操作する方法を基礎から学び、シンプルなサンプルコード、データモデリング、CRUD操作、演習問題までをカバーします。
初心者の方にもわかりやすいよう、順を追って解説しますので、ぜひ最後までご覧ください。
環境準備
Cassandraのインストール
- オフィシャルサイトから最新のCassandraをダウンロードし、インストールしてください。
- Windows/macOS/Linuxいずれでも同様に動作します。
Python環境の用意
- Python3.7以上を推奨します。
- 仮想環境(venvなど)を作成し、依存ライブラリを分離しましょう。
python3 -m venv cass_env
source cass_env/bin/activate # Windowsの場合: cass_env\Scripts\activate
Cassandraの基本概念
- ノード (Node): データを保持するサーバー単位。
- クラスタ (Cluster): 複数のノードで構成されるCassandra全体。
- キー スペース (Keyspace): データベースのような役割。レプリケーション設定を含む。
- テーブル (Table): RDBのテーブルに相当。列定義と主キーを持つ。
- パーティションキー (Partition Key): データ分散の単位。頻繁にアクセスするカラムを選ぶ。
- クラスタキー (Clustering Key): パーティション内の並び順を決定する。
Pythonドライバのインストール
Cassandra用の公式Pythonドライバは cassandra-driver です。pipでインストールします。
pip install cassandra-driver
クラスターへの接続とセッション取得
まずはCassandraクラスタへ接続し、操作の起点となるセッションを取得します。
from cassandra.cluster import Cluster
# localhostに立てた1ノードクラスタへ接続
cluster = Cluster(['127.0.0.1'], port=9042)
session = cluster.connect()
print("接続成功:", session)
- Cluster() では接続先ノードのIPリストとポートを指定。
- connect() はデフォルトキー スペースなしで接続。キースペースを指定する場合は cluster.connect(‘keyspace_name’)。
キースペースとテーブルの作成
キースペースの作成
session.execute("""
CREATE KEYSPACE IF NOT EXISTS sample
WITH replication = {'class': 'SimpleStrategy', 'replication_factor': '1'}
""")
# キースペースを指定して接続し直す
session.set_keyspace('sample')
SimpleStrategy は学習用。実運用では NetworkTopologyStrategy を用います。
テーブルの作成
session.execute("""
CREATE TABLE IF NOT EXISTS users (
user_id UUID,
name text,
age int,
PRIMARY KEY (user_id)
)
""")
データの挿入(INSERT)
import uuid
insert_cql = "INSERT INTO users (user_id, name, age) VALUES (%s, %s, %s)"
session.execute(insert_cql, (uuid.uuid4(), 'Alice', 30))
session.execute(insert_cql, (uuid.uuid4(), 'Bob', 25))
- CQLの変数プレースホルダーは %s。
- Pythonタプルで値を渡すことで、安全にバインドされる。
データの取得(SELECT)
rows = session.execute("SELECT user_id, name, age FROM users")
for row in rows:
print(f"ID:{row.user_id} 名前:{row.name} 年齢:{row.age}")
execute() が返す ResultSet はイテレータとして扱えます。
特定条件で取得する例
prepared = session.prepare("SELECT * FROM users WHERE user_id = ?")
bound = prepared.bind([target_uuid])
row = session.execute(bound).one()
if row:
print(row.name, row.age)
データの更新・削除(UPDATE/DELETE)
UPDATE
update_cql = "UPDATE users SET age = %s WHERE user_id = %s"
session.execute(update_cql, (31, alice_uuid))
DELETE
delete_cql = "DELETE FROM users WHERE user_id = %s"
session.execute(delete_cql, (bob_uuid,))
WHERE句には必ず完全なパーティションキー(および必要に応じてクラスタキー)を指定します。
データモデル設計のポイント
- クエリファースト設計
Cassandraはクエリ最適化型。先に必要な問い合わせパターンを決め、テーブルを設計。 - 冗長化を許容
複数のテーブルに同じデータを持たせ、アクセスを高速化。 - パーティションキーの選び方
データ分散の偏りを防ぐため、高カードinality(多様な値)を持つカラムを選択。 - TTL(Time to Live)の活用
自動削除が必要なデータにはTTLを設定。
演習問題と解答例
演習問題
- キースペース library を作成し、books テーブルを定義してください。
- テーブルには book_id (UUID), title (text), author (text), published_year (int) を持たせ、book_id をパーティションキーとする。
- books テーブルに3件のデータをINSERTし、全件取得して表示するコードを書いてください。
- データ例:
- “The Hobbit”, “J.R.R. Tolkien”, 1937
- “1984”, “George Orwell”, 1949
- “Clean Code”, “Robert C. Martin”, 2008
- データ例:
- 特定の published_year が 1949 の書籍をSELECTするコードを作成してください。
- published_year はクラスタキーとして追加定義し、条件検索できるように設計・実装する。
解答例
from cassandra.cluster import Cluster
import uuid
# 接続とキースペース作成
cluster = Cluster(['127.0.0.1'])
session = cluster.connect()
session.execute("""
CREATE KEYSPACE IF NOT EXISTS library
WITH replication = {'class': 'SimpleStrategy', 'replication_factor': '1'}
""")
session.set_keyspace('library')
# テーブル作成(published_yearをクラスタキーに追加)
session.execute("""
CREATE TABLE IF NOT EXISTS books (
book_id UUID,
title text,
author text,
published_year int,
PRIMARY KEY ((book_id), published_year)
)
""")
# データ挿入
insert_cql = "INSERT INTO books (book_id, title, author, published_year) VALUES (%s, %s, %s, %s)"
books = [
('The Hobbit', 'J.R.R. Tolkien', 1937),
('1984', 'George Orwell', 1949),
('Clean Code', 'Robert C. Martin', 2008),
]
for title, author, year in books:
session.execute(insert_cql, (uuid.uuid4(), title, author, year))
# 全件取得
print("=== 全件表示 ===")
for row in session.execute("SELECT title, author, published_year FROM books"):
print(row.title, row.author, row.published_year)
# published_year=1949の書籍取得
print("\n=== 1949年の書籍 ===")
# まずインデックスを作成(年で検索可能にする)
session.execute("CREATE INDEX IF NOT EXISTS idx_year ON books (published_year)")
rows = session.execute("SELECT title, author FROM books WHERE published_year = 1949")
for row in rows:
print(row.title, row.author)
まとめ
この記事では、PythonからCassandraを操作するための基本手順を、環境構築からデータモデリング、CRUD操作まで解説しました。
Cassandra特有の「クエリファースト設計」や「パーティションキー選定」のポイントも押さえ、演習問題で理解を深められたかと思います。
分散データベースの基礎を学びながら、Pythonと組み合わせてスケーラブルなアプリケーション開発に挑戦してみましょう!