2016-05-06 7 views
0

私はFlask-RESTfulベースのAPIを持っていますが、現在は2つの青写真があり、互換性のない変更でAPIをバージョンアップできます。異なったモデルblueprintsのresource_fields

from api_1_0 import api_bp as api_1_0_blueprint 
app.register_blueprint(api_1_0_blueprint, url_prefix='/api/v1.0') 

from api_1_1 import api_bp as api_1_1_blueprint 
app.register_blueprint(api_1_1_blueprint, url_prefix='/api/v1.1') 

私は後方互換性のない変更(エンドポイントの削除など)が必要なときはいつでも、新しい青写真を作成します。現在、青写真はすべて同じファイルmodels.pyを共有しており、データベーステーブルと各モデルのJSON表現を定義しています。

特定のリソースフィールドemailstringデータタイプからarray[string]に変更される新しいバージョンのAPIを作成する必要があります。 APIの既存のバージョンでは、元のリソース表現を保持する必要があります。

新しい青写真 v1.2が、それは自分の resource_fields定義だが、そうすることで、私はこのエラーで終わることができますように、私はそれぞれの青写真フォルダに models.pyファイルを配置しようとしている

sqlalchemy.exc.InvalidRequestError: Table '' is already defined for this MetaData instance. Specify 'extend_existing=True' to redefine options and columns on an existing Table object.

私はこのことを理解していますすべての青写真について同じデータベーステーブルを本質的に定義しているからです。本当に私が望むのは、データベーススキーマが常にすべてのAPIバージョンで同じになるため、青写真ごとにresource_fieldsを変更することだけです。変更可能なJSONレスポンスです。どのように私は青写真あたりresource_fieldsを変更することができ、この設定を考えると

(私は新しいフィールドを作成する@propertyデコレータを使用しますか)?

以下は、私のプロジェクトのサンプルコードです(簡略化されています)。

アプリ/ models.pyからhttps://gist.github.com/MattHealy/4c9d2c03615e3381774235bbbc398437

from app import db 
from flask.ext.restful import fields 

@swagger.model 
class Contact(db.Model): 

     resource_fields = { 
     'email': fields.String 
     } 

     email = db.Column(db.String(100)) 

アプリ/ api_1_1 /リソース/ contacts.pyからhttps://gist.github.com/MattHealy/556c93fe33a929e469ae18bf76db83b1

from flask.ext.restful import Resource, marshal, reqparse 
from ... models import Contact 

class ContactAPI(Resource): 

    "Retrieve details of a single contact" 
    @swagger.operation(
     nickname = "contact", 
     responseClass=Contact.__name__, 
     parameters=[ 
      { 
       "name": "id", 
       "description": "ID of the contact", 
       "required": True, 
       "allowMultiple": False, 
       "dataType": "int", 
       "paramType": "path" 
      }, 
     ], 
     responseMessages=[ 
      { 
       "code": 200, 
       "message": "Contact retrieved" 
      }, 
      ], 
     summary="Get details of a single contact", 
     ) 
    def get(self, id): 
     contact = Contact.query.get(id) 
     return { 'contact': marshal(contact, Contact.resource_fields) } 

答えて

1

あなただけ使用することができます異なる(ローカルで生成されました)青写真ごとのresource_fields dict具体的には、ContactAPIクラスの属性としてresource_fieldsを使用し、それをマーシャリング関数に渡すことができます。

上記の場合(電子メールフィールドのタイプの変更)では、取得する可能性のある出力のタイプに合わせてカスタムFieldsクラス(fields.Rawに基づいて)を作成する必要があると思います。

関連する問題