7

私の目標は、Python Web アプリケーションに Flask と SQLAlchemy を使用して、次のことができるシステムを作成することです。

  1. 既存の PostgreSQL DB からデータ モデルをインポートし、これらを対応する SQLAlchemy モデルのフィールドにマッピングします
  2. これらの SQLAlchemy モデルを使用して、スキーマを自動的に生成します。このスキーマは、ユーザーが送信したデータに対してデータ検証を実行するために使用されます (現在、マシュマロを使用しようとしていますが、他の提案も受け付けています)。
  3. 手順 2 で生成されたスキーマを使用して、JSON 応答の書式設定を実行します (現在、JsonAPI のスキーマに従って応答を書式設定しようとしています。これは必要に応じて変更される可能性がありますが、私はそれを好みます)。

これらはすべて単一のレイヤーにパッケージ化され、API を作成するときに単純なデータ アクセス、検証、および応答の書式設定を可能にする必要があります。できれば、DB に既に存在する定義を超えてデータ モデルやスキーマを手動で定義する必要はありません。これは私の質問につながります:

既存のフレームワークを利用して、達成しようとしているすべてのことを実行できますか? すべてを実行できる 1 つのライブラリがあるとは思いませんが、いくつかの既存のフレームワークを活用できるようになることを望んでいます。ただし、特に手順 2 と 3 で直接競合が発生します。これまで使用しようとしてきたスタックは次のとおりです。

  • Flask (私の Web フレームワーク)
  • SQLAlchemy (リフレクションを介してデータにアクセスするために使用されます。以下を参照してください)
  • Flask-Marshmallow (データ検証用のスキーマを生成するには)
  • Marshmallow-JsonAPI (JsonAPI 仕様に従って JSON 応答をフォーマットするには)

ステップ1の解決策があります:SQLAlchemyのリフレクション。これにより、既存の DB のテーブルを読み取り、それらを SQLAlchemy モデルにマップできます。これは美しく機能します。

ステップ 2 と 3 の組み合わせは、ぼやけているところです。Flask-Marshmallow と Marshmallow-JsonAPI を使用しようとしています。Flask-Marshmallow にはModelSchema クラスがあり、既存の SQLAlchemy モデルを渡すことでスキーマを生成できます。ステップ 1 で生成された SQLAlchemy モデルを渡すことができ、ステップ 2 の基準を満たします。Marshmallow-JsonAPI に関しては、モデルのスキーマを定義できる機能があり、JSONAPI 準拠の応答を自動的に作成します。 、ステップ 3 の基準を満たしています。これらの各フレームワークを個別に取得して、必要なことを実行できます。

残念ながら、私のスキーマは Flask-Marshmallow と Marshmallow-JSONAPI の両方のスキーマ クラスから継承する必要があるため、問題が発生します。「ダミー」クラスの私のモデルは次のようになります。

import flask
from marshmallow_jsonapi import Schema, fields
from sqlalchemy.ext.declarative import DeferredReflection
from flask_marshmallow import Marshmallow
from flask_sqlalchemy import SQLAlchemy

app = flask.Flask(__name__)
DB = SQLAlchemy()
DB.init_app(app)
MA = Marshmallow(app)
DeferredReflection.prepare(DB.get_engine(app))

class Dummy(DeferredReflection, DB.Model):
    __tablename__ = "dummy"  # This model will be reflected from the Dummy table


class DummySchema(MA.ModelSchema, Schema):  # The problem line
    class Meta:
        model = Dummy  # Create schema for the Dummy model

API を起動しようとすると、次のような奇妙なエラーが発生します。

api_1        | [2017-01-05 23:16:13,379] ERROR in app: Exception on /api/dummy [POST]
api_1        | Traceback (most recent call last):
api_1        |   File "/usr/local/lib/python3.5/site-packages/flask/app.py", line 1612, in full_dispatch_request
api_1        |     rv = self.dispatch_request()
api_1        |   File "/usr/local/lib/python3.5/site-packages/flask/app.py", line 1598, in dispatch_request
api_1        |     return self.view_functions[rule.endpoint](**req.view_args)
api_1        |   File "/usr/local/lib/python3.5/site-packages/flask_restful/__init__.py", line 477, in wrapper
api_1        |     resp = resource(*args, **kwargs)
api_1        |   File "/usr/local/lib/python3.5/site-packages/flask/views.py", line 84, in view
api_1        |     return self.dispatch_request(*args, **kwargs)
api_1        |   File "/usr/local/lib/python3.5/site-packages/flask_restful/__init__.py", line 587, in dispatch_request
api_1        |     resp = meth(*args, **kwargs)
api_1        |   File "/dummyproj/api/src/dummyproj/api/v1/dummy_resource.py", line 34, in post
api_1        |     dummy_schema = dummy.DummySchema()
api_1        |   File "/usr/local/lib/python3.5/site-packages/marshmallow_sqlalchemy/schema.py", line 143, in __init__
api_1        |     super(ModelSchema, self).__init__(*args, **kwargs)
api_1        |   File "/usr/local/lib/python3.5/site-packages/marshmallow_jsonapi/schema.py", line 81, in __init__
api_1        |     super(Schema, self).__init__(*args, **kwargs)
api_1        |   File "/usr/local/lib/python3.5/site-packages/marshmallow/schema.py", line 358, in __init__
api_1        |     self._update_fields(many=many)
api_1        |   File "/usr/local/lib/python3.5/site-packages/marshmallow/schema.py", line 750, in _update_fields
api_1        |     self.__set_field_attrs(ret)
api_1        |   File "/usr/local/lib/python3.5/site-packages/marshmallow/schema.py", line 772, in __set_field_attrs
api_1        |     self.on_bind_field(field_name, field_obj)
api_1        |   File "/usr/local/lib/python3.5/site-packages/marshmallow_jsonapi/schema.py", line 164, in on_bind_field
api_1        |     field_obj.load_from = self.inflect(field_name)
api_1        |   File "/usr/local/lib/python3.5/site-packages/marshmallow_jsonapi/schema.py", line 190, in inflect
api_1        |     return self.opts.inflect(text) if self.opts.inflect else text
api_1        | AttributeError: 'SchemaOpts' object has no attribute 'inflect'

私の Schema クラスは 2 つの異なるスーパークラスから継承しているため、問題が発生しているようです。2 つのマシュマロ ライブラリはかなり互換性があると思いますが、これには問題があるようです。

このすべての結果は、次に何を試すべきかよくわからないということです. マシュマロ フレームワークに関する特定のアドバイスを実際に期待しているわけではなく、私の一連の考えを示そうとしているだけです。この種の設計に関するベスト プラクティスはありますか、それとも一度に多くのことを解決しようとしていますか?

(Python と SO の両方に新しい - これのいずれかが不明な場合はお詫びします)。

4

1 に答える 1