2017-03-19 12 views
4

SQLAlchemyモデルを使用してFlask APIを作成しています。それは簡単に自分自身をダンプすることができますので、私はスキーマを持つように各モデルをしたいと思いますSQLAlchemyモデルのマシュマロスキーマを動的に生成する方法

class EntrySchema(ma.ModelSchema): 
    class Meta: 
     model = Entry 

: 私は私が持っているすべてのモデルのためのスキーマを定義したくない、私はこのすべての時間を行うにはしたくありません。 デフォルトのスキーマを作成し、Schema.Meta.modelは動作しませんでした設定:

class Entry(db.Model): 
    __tablename__ = 'entries' 

    id = db.Column(db.Integer, primary_key=True) 
    started_at = db.Column(db.DateTime) 
    ended_at = db.Column(db.DateTime) 
    description = db.Column(db.Text()) 

    def __init__(self, data): 
     for key in data: 
      setattr(self, key, data[key]) 

     self.Schema = Schema 
     self.Schema.Meta.model = self.__class__ 

    def dump(self): 
     schema = self.Schema() 
     result = schema.dump(self) 
     return result 


class Schema(ma.ModelSchema): 
    class Meta: 
     pass 

なぜモデルと一般的なスキーマが宣言モデルとスキーマとは異なる上書きされますか?クラス属性Entry.Schemaとして利用できるようになります

def add_schema(cls): 
    class Schema(ma.ModelSchema): 
     class Meta: 
      model = cls 
    cls.Schema = Schema 
    return cls 

、その後

@add_schema 
class Entry(db.Model): 
    ... 

スキーマ:

答えて

4

はあなたのモデルにSchemaを追加し、クラスのデコレータを作成することができます。

元の試行が失敗する理由は、marshmallow Schemaクラスがcustom metaclassを使用して作成され、クラス本体の実行で作成された名前空間とdoes its thingを検査することです。すでに作成されたクラスを変更すると、それは遅すぎます。

あなたがPythonのメタクラスに精通していない場合は、language referenceでそれらについて読んでください。彼らは素晴らしいことと大きな誤用を許す道具です。

0

marshmallow recipesは、一般的なスキーマオプションを基本クラスにスローするための代替オプションをいくつか指定しています。

# myproject/schemas.py 

from marshmallow_sqlalchemy import ModelSchema 

from .db import Session 

class BaseSchema(ModelSchema): 
    class Meta: 
     sqla_session = Session 

、その後、基本スキーマを拡張します:ここではストレートのドキュメントからの簡単な例です

# myproject/users/schemas.py 

from ..schemas import BaseSchema 
from .models import User 

class UserSchema(BaseSchema): 

    # Inherit BaseSchema's options 
    class Meta(BaseSchema.Meta): 
     model = User 
この方法の利点は、あなたが特定のモデルによりデ/シリアライズを追加できることです

リンク先のドキュメントの例とレシピ