はじめに
データ生成ライブラリとして有名な Faker を活用して、親子関係のあるデータ を自由自在に生成する方法を紹介します。
例えば、以下のようなケースに対応できます。
-
顧客 (Parent) と 注文 (Child)
-
customer_id
をキーとして、orders
にcustomer_id
を持たせる
-
-
商品カテゴリ (Parent) と サブカテゴリ (Child)
-
category_id
をキーとして、sub_categories
にparent_category_id
を設定
-
-
ブログのユーザ (Parent) と 記事 (Child)
-
user_id
をキーとして、posts
にuser_id
を持たせる
-
Faker の標準機能だけでは対応しきれないため、カスタムプロバイダ を作成する方法を解説します。
環境設定
- Python 3.x (この記事では 3.9 以上を想定)
- Faker ライブラリ
- Google Colab やローカルの Python 環境
pip install Faker
Google Colab では、ノートブックの最初のセルで上記コマンドを実行してください。
方法 1: 親子をセットで生成する
親1レコードと子Nレコードをまとめて生成 するカスタムプロバイダを作成します。
実装
from faker import Faker
from faker.providers import BaseProvider
import random
from datetime import datetime
fake = Faker()
fake.seed_instance(1234)
class ParentAndChildDataProvider(BaseProvider):
def create_parent_with_children(self, num_children=3):
"""
親1件、子N件を生成し、親のIDを子に紐づける
"""
parent_id = f"CUST-{random.randint(1000,9999)}"
parent_data = {
"customer_id": parent_id,
"customer_name": fake.name(),
"registered_date": fake.date_between('-1y', 'today')
}
children_data = []
for _ in range(num_children):
order_id = f"ORD-{random.randint(10000,99999)}"
order_date = fake.date_between(start_date=parent_data['registered_date'], end_date='today')
total_amount = random.randint(1000, 20000)
child = {
"order_id": order_id,
"customer_id": parent_id,
"order_date": order_date,
"total_amount": total_amount,
}
children_data.append(child)
return {
"parent": parent_data,
"children": children_data
}
# プロバイダ追加
fake.add_provider(ParentAndChildDataProvider)
# 実行例
print(fake.create_parent_with_children(num_children=3))
方法 2: 先に親を生成し、子を後で割り当てる
データベースのように 親リストを先に作成 し、後で 子データを親に紐づける 方法です。
実装
class ParentChildSeparateProvider(BaseProvider):
def create_parents(self, n=5):
""" 親データを n 件生成 """
parent_list = []
for _ in range(n):
parent_id = f"CUST-{random.randint(1000,9999)}"
parent = {
"customer_id": parent_id,
"customer_name": fake.name(),
"registered_date": fake.date_between('-1y', 'today')
}
parent_list.append(parent)
return parent_list
def create_children(self, parents, num_children=3):
""" 既存の親データを参照しながら、子データを生成 """
children_list = []
for _ in range(num_children):
parent = random.choice(parents)
order_id = f"ORD-{random.randint(10000,99999)}"
order_date = fake.date_between(start_date=parent['registered_date'], end_date='today')
total_amount = random.randint(1000, 20000)
child = {
"order_id": order_id,
"customer_id": parent["customer_id"],
"order_date": order_date,
"total_amount": total_amount,
}
children_list.append(child)
return children_list
# プロバイダ追加
fake.add_provider(ParentChildSeparateProvider)
# 親データを10件生成
parents_data = fake.create_parents(n=10)
print(f"--- Parents ---\n{parents_data}\n")
# 子データを20件生成し、親IDをランダムに割り当て
children_data = fake.create_children(parents=parents_data, num_children=20)
print(f"--- Children ---")
for c in children_data:
print(c)
まとめ
- Faker のカスタムプロバイダを利用して、親子関係のあるデータを簡単に生成できる
- 親と子をセットで生成する方法 と 親リストを先に作って子に紐づける方法 の2パターンを紹介
- 実データに近い 外部キーのような制約 を持ったモックデータを作れる
これを活用すれば、テストデータや開発時のモックデータ生成がスムーズになります。ぜひ活用してみてください!