ブループリントを使用してFlaskで「モジュラーアプリケーション」を作成しようとしています。
ただし、モデルを作成するときに、db
Flask-SQLAlchemyによって提供されるオブジェクトを取得するためにアプリを参照する必要があるという問題が発生しています。複数のアプリでいくつかのブループリントを使用できるようにしたいので(Djangoアプリの使用方法と同様)、これは適切なソリューションではありません。*
- switcharooを実行し、ブループリントに
db
インスタンスを作成させることができます。インスタンスは、アプリが残りのブループリントと一緒にインポートします。ただし、モデルを作成したい他のブループリントは、アプリではなく、そのブループリントからインポートする必要があります。
したがって、私の質問は次のとおりです。
- 後で使用されているアプリを意識せずにブループリントにモデルを定義させ、複数のブループリントをまとめる方法はありますか?これは、ブループリントからアプリモジュール/パッケージをインポートする必要があることを意味します。
- 私は最初から間違っていますか?ブループリントは、アプリから独立して再配布可能であることを意図していませんか(àlaDjangoアプリ)?
- そうでない場合は、そのようなものを作成するためにどのパターンを使用する必要がありますか?フラスコ拡張?単純にそれを行うべきではありません-そして多分すべてのモデル/スキーマをRubyonRailsで一元化するのでしょうか?
編集
declarative_base()
:私は今これについて自分で考えていましたが、モデルを宣言するときに持っている必要があるため、これはFlaskよりもSQLAlchemyに関連している可能性があります。そして、それはとにかくどこかから来なければなりません!おそらく最善の解決策は、Ruby on Railsのように、プロジェクトのスキーマを1つの場所で定義し、それを分散させることです。宣言型SQLAlchemyクラス定義は、実際にはDjangoのmodels.pyよりもschema.rbに似ています。これにより、( alembicまたはsqlalchemy-migrateからの)移行も簡単に使用できるようになると思います。
例を提供するように求められたので、簡単なことをしましょう。データベースに保存されている単純な「静的」コンテンツである「フラットページ」を説明する青写真があるとします。ショートネーム(URL用)、タイトル、本文のみのテーブルを使用します。これはsimple_pages/__init__.py
:
from flask import Blueprint, render_template
from .models import Page
flat_pages = Blueprint('flat_pages', __name__, template_folder='templates')
@flat_pages.route('/<page>')
def show(page):
page_object = Page.query.filter_by(name=page).first()
return render_template('pages/{}.html'.format(page), page=page_object)
次に、このブループリントに独自のモデルを定義させるとよいでしょう(これはsimple_page/models.py
):
# TODO Somehow get ahold of a `db` instance without referencing the app
# I might get used in!
class Page(db.Model):
name = db.Column(db.String(255), primary_key=True)
title = db.Column(db.String(255))
content = db.Column(db.String(255))
def __init__(self, name, title, content):
self.name = name
self.title = title
self.content = content
この質問は以下に関連しています:
db
その他にもさまざまですが、すべての返信はアプリのインスタンスをインポートするか、その逆を行うことに依存しているようです。「大規模なアプリのハウツー」ウィキページでも、「アプリを設計図にインポートする」パターンが使用されています。
*公式ドキュメントには、ブループリントが「含まれている」アプリを気にせずにルート、ビュー、テンプレート、アセットを作成する方法が示されているため、ブループリントは通常、アプリ間で再利用できるはずです。ただし、このモジュール性は、独立したモデルがなければそれほど有用ではないようです。
ブループリントはアプリに複数回フックされる可能性があるため、ブループリントにモデルを含めるのは単に間違ったアプローチである可能性がありますか?