SQLAlchemyを用いたORMによるデータベース操作:エンティティとテーブルの操作
データベースにおけるエンティティとテーブルの違い
エンティティとは、現実世界のあるまとまりの情報を抽象化した概念を表します。例えば、「顧客」、「商品」、「注文」などがエンティティにあたります。エンティティは、固有の特性(属性)を持ち、互いに関係性を持つ場合があります。
一方、テーブルは、データベース内にデータを格納するための構造体です。行と列で構成され、各行はエンティティの個々のインスタンス(レコード)を表します。列は、エンティティの属性に対応し、それぞれの属性の値を格納します。
簡単に言えば、エンティティは「何」を表す概念であり、テーブルは「どのように」データを格納・管理するための構造と言えます。
例:顧客管理システム
顧客管理システムを例に考えてみましょう。
テーブル
- 顧客テーブル:顧客ID(主キー)、氏名、住所、メールアドレスなど
- 商品テーブル:商品ID(主キー)、商品名、価格、在庫数など
- 注文テーブル:注文ID(主キー)、顧客ID、商品ID、注文個数、注文日など
エンティティ
- 商品:商品ID、商品名、価格、在庫数など
上記のように、エンティティは現実世界の情報を抽象化し、テーブルはデータを効率的に管理するための構造として役割を果たします。
- テーブル:データベース内にデータを格納するための構造
- エンティティ:現実世界の情報を抽象化した概念
# エンティティクラス定義
class Customer:
def __init__(self, customer_id, name, address, email):
self.customer_id = customer_id
self.name = name
self.address = address
self.email = email
class Product:
def __init__(self, product_id, name, price, stock):
self.product_id = product_id
self.name = name
self.price = price
self.stock = stock
class Order:
def __init__(self, order_id, customer_id, product_id, quantity, order_date):
self.order_id = order_id
self.customer_id = customer_id
self.product_id = product_id
self.quantity = quantity
self.order_date = order_date
# テーブル定義
def create_tables(db):
# 顧客テーブル
db.create_table(
'customers',
columns=[
Column('customer_id', Integer, primary_key=True),
Column('name', String(255)),
Column('address', String(255)),
Column('email', String(255)),
]
)
# 商品テーブル
db.create_table(
'products',
columns=[
Column('product_id', Integer, primary_key=True),
Column('name', String(255)),
Column('price', Float),
Column('stock', Integer),
]
)
# 注文テーブル
db.create_table(
'orders',
columns=[
Column('order_id', Integer, primary_key=True),
Column('customer_id', Integer, ForeignKey('customers.customer_id')),
Column('product_id', Integer, ForeignKey('products.product_id')),
Column('quantity', Integer),
Column('order_date', DateTime),
]
)
# データ操作例
def insert_customer(db, customer):
db.session.add(customer)
db.session.commit()
def select_all_customers(db):
return db.session.query(Customer).all()
def update_customer_address(db, customer_id, new_address):
customer = db.session.query(Customer).filter_by(customer_id=customer_id).first()
customer.address = new_address
db.session.commit()
def delete_customer(db, customer_id):
db.session.query(Customer).filter_by(customer_id=customer_id).delete()
db.session.commit()
# サンプルコード実行
if __name__ == '__main__':
# データベース接続
from sqlalchemy import create_engine
engine = create_engine('sqlite:///database.db')
db = SessionLocal(bind=engine)
# テーブル作成
create_tables(db)
# 顧客データ挿入
customer1 = Customer(1, '田中 太郎', '東京都千代田区', '[email protected]')
customer2 = Customer(2, '佐藤 花子', '神奈川県横浜市', '[email protected]')
insert_customer(db, customer1)
insert_customer(db, customer2)
# 顧客データ一覧取得
customers = select_all_customers(db)
for customer in customers:
print(f'顧客ID: {customer.customer_id}')
print(f'氏名: {customer.name}')
print(f'住所: {customer.address}')
print(f'メールアドレス: {customer.email}')
print('-----------------')
# 顧客情報の更新
update_customer_address(db, 1, '東京都港区')
# 顧客情報の削除
delete_customer(db, 2)
ORMは、エンティティをPythonなどのプログラミング言語のクラスとして表現し、データベースとの操作を簡略化するフレームワークです。エンティティ間の関係性を自然な形で記述でき、SQLクエリを直接記述するよりもコードが読みやすく、保守しやすいというメリットがあります。
例:SQLAlchemyを用いたORM
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
# エンティティクラス定義
Base = declarative_base()
class Customer(Base):
__tablename__ = 'customers'
customer_id = Column(Integer, primary_key=True)
name = Column(String(255))
address = Column(String(255))
email = Column(String(255))
class Product(Base):
__tablename__ = 'products'
product_id = Column(Integer, primary_key=True)
name = Column(String(255))
price = Column(Float)
stock = Column(Integer)
class Order(Base):
__tablename__ = 'orders'
order_id = Column(Integer, primary_key=True)
customer_id = Column(Integer, ForeignKey('customers.customer_id'))
product_id = Column(Integer, ForeignKey('products.product_id'))
quantity = Column(Integer)
order_date = Column(DateTime)
# データベース接続
engine = create_engine('sqlite:///database.db')
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
db = Session()
# データ操作例
# 顧客データ挿入
customer1 = Customer(name='田中 太郎', address='東京都千代田区', email='[email protected]')
customer2 = Customer(name='佐藤 花子', address='神奈川県横浜市', email='[email protected]')
db.add(customer1)
db.add(customer2)
db.commit()
# 顧客データ一覧取得
customers = db.query(Customer).all()
for customer in customers:
print(f'顧客ID: {customer.customer_id}')
print(f'氏名: {customer.name}')
print(f'住所: {customer.address}')
print(f'メールアドレス: {customer.email}')
print('-----------------')
# 顧客情報の更新
customer1.address = '東京都港区'
db.commit()
# 顧客情報の削除
db.delete(customer2)
db.commit()
NoSQLデータベース
NoSQLデータベースは、エンティティとテーブルの関係性を従来のRDBMSとは異なる柔軟な方法で表現することができます。スキーマレスな構造を採用するため、データ構造の変化に柔軟に対応でき、大規模なデータの処理にも適しています。
例:MongoDBを用いたNoSQLデータベース
import pymongo
# データベース接続
client = pymongo.MongoClient('mongodb://localhost:27017/')
db = client['test']
# コレクション(テーブル相当)作成
customers_collection = db['customers']
products_collection = db['products']
orders_collection = db['orders']
# データ操作例
# 顧客データ挿入
customer1 = {'name': '田中 太郎', 'address': '東京都千代田区', 'email': '[email protected]'}
customer2 = {'name': '佐藤 花子', 'address': '神奈川県横浜市', 'email': '[email protected]'}
customers_collection.insert_many([customer1, customer2])
# 顧客データ一覧取得
customers = customers_collection.find()
for customer in customers:
print(f'顧客ID: {customer["_id"]}') # _idはMongoDBの自動生成ID
print(f'氏名: {customer["name"]}')
print(f'住所: {customer["address"]}')
print(f'メールアドレス: {customer["email"]}')
print('-----------------')
# 顧客情報の更新
customers_collection.update_one({'name': '田中 太郎'}, {'$set': {'address': '東京都港区'}})
database