BOP - The Future of Creative Engineers -


← ホームに戻る

marshmallowの基礎

marshmallowは、複雑なデータ型(オブジェクトなど)とプリミティブなPythonデータ型(int, str, dictなど)の間でオブジェクトのシリアライズ(直列化)とデシリアライズ(非直列化)を行うためのライブラリです。主に以下のような目的で使用されます。

APIのデータ変換: リクエストやレスポンスのJSONなどのデータ形式とPythonオブジェクトを相互に変換する。

データの検証: 入力データの型や形式を定義し、バリデーションを行う。

marshmallowの中心となるのは「スキーマ (Schema)」です。スキーマは、データの構造と型を定義するクラスです。


よく使うコマンドと概念

スキーマの定義

スキーマは marshmallow.Schema を継承して作成します。スキーマの属性として、各フィールドを定義します。

from marshmallow import Schema, fields

class UserSchema(Schema):
    id = fields.Int(dump_only=True)  # シリアライズ専用
    name = fields.Str(required=True)  # 必須フィールド
    email = fields.Email()
    created_at = fields.DateTime(dump_only=True)

シリアライズ (Serialization)

PythonオブジェクトをJSONなどのプリミティブなデータ構造に変換します。

user_data = {"id": 1, "name": "Alice", "email": "alice@example.com"}
schema = UserSchema()
result = schema.dump(user_data)
print(result)
# {'id': 1, 'name': 'Alice', 'email': 'alice@example.com', 'created_at': ...}

複数のオブジェクトをシリアライズする場合は dump メソッドに many=True を指定します。

users_data = [{"id": 1, "name": "Alice", "email": "alice@example.com"}, {"id": 2, "name": "Bob", "email": "bob@example.com"}]
schema = UserSchema()
results = schema.dump(users_data, many=True)
print(results)
# [{'id': 1, 'name': 'Alice', 'email': 'alice@example.com', 'created_at': ...}, {'id': 2, 'name': 'Bob', 'email': 'bob@example.com', 'created_at': ...}]

デシリアライズ (Deserialization)

JSONなどのプリミティブなデータ構造をPythonオブジェクトに変換します。また、バリデーションも同時に行われます。

json_data = {"name": "Charlie", "email": "charlie@example.com"}
schema = UserSchema()
result = schema.load(json_data)
print(result)
# {'name': 'Charlie', 'email': 'charlie@example.com'}

デシリアライズ時にバリデーションエラーが発生した場合、marshmallow.exceptions.ValidationError が送出されます。エラー情報は errors 属性で確認できます。

invalid_data = {"email": "invalid-email"}
schema = UserSchema()
try:
    result = schema.load(invalid_data)
except marshmallow.exceptions.ValidationError as err:
    print(err.messages)
    # {'name': ['Missing data for required field.'], 'email': ['Not a valid email address.']}

複数のデータをデシリアライズする場合は load メソッドに many=True を指定します。

フィールド

よく使うフィールドの種類: * fields.Str(): 文字列
fields.Int(): 整数
fields.Float(): 浮動小数点数
fields.Boolean(): 真偽値
fields.DateTime(): 日付と時間
fields.Date(): 日付
fields.Time(): 時間
fields.List(fields.Nested(NestedSchema())): リスト(ネストされたスキーマを含む)
fields.Nested(RelatedSchema()): 別のスキーマへの参照

バリデーション

フィールドの引数 validate にバリデーション関数や marshmallow.validate の提供するバリデーターを指定することで、データの検証を行うことができます。

from marshmallow import Schema, fields, validate

class ItemSchema(Schema):
    name = fields.Str(validate=validate.Length(min=3, max=10))
    price = fields.Float(validate=validate.Range(min=0))

item_data = {"name": "Pen", "price": 1.5}
schema = ItemSchema()
result = schema.load(item_data)
print(result)
# {'name': 'Pen', 'price': 1.5}

invalid_item_data = {"name": "Po", "price": -1}
try:
    result = schema.load(invalid_item_data)
except marshmallow.exceptions.ValidationError as err:
    print(err.messages)
    # {'name': ['Length must be between 3 and 10.'], 'price': ['Must be greater than or equal to 0.']}

使用例

APIのリクエスト/レスポンスのシリアライズとデシリアライズ

FlaskのようなWebフレームワークと組み合わせて、APIのエンドポイントでデータの変換と検証を行う例です。

from flask import Flask, request, jsonify
from marshmallow import Schema, fields, ValidationError

app = Flask(__name__)

class BookSchema(Schema):
    id = fields.Int(dump_only=True)
    title = fields.Str(required=True)
    author = fields.Str(required=True)

book_schema = BookSchema()
books_schema = BookSchema(many=True)

books = []
next_id = 1

@app.route('/books', methods=['GET'])
def get_books():
    return jsonify(books_schema.dump(books))

@app.route('/books', methods=['POST'])
def add_book():
    try:
        book_data = book_schema.load(request.get_json())
        global next_id
        book_data['id'] = next_id
        books.append(book_data)
        next_id += 1
        return jsonify(book_schema.dump(book_data)), 201
    except ValidationError as err:
        return jsonify({'errors': err.messages}), 400

if __name__ == '__main__':
    app.run(debug=True)

この例では、BookSchema を定義し、GETリクエストで書籍のリストをシリアライズしてJSONで返したり、POSTリクエストで送られてきたJSONデータをデシリアライズして新しい書籍オブジェクトを作成したりしています。デシリアライズ時にバリデーションエラーが発生した場合は、エラーメッセージをJSONで返しています。

marshmallowは、データの変換と検証をシンプルかつ効率的に行うための強力なツールです。ぜひご自身のプロジェクトで活用してみてください。