Flask-Migrate を使用して、その例を確認します。
_from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
from flask.ext.script import Manager
from flask.ext.migrate import Migrate, MigrateCommand
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///app.db'
db = SQLAlchemy(app)
migrate = Migrate(app, db)
manager = Manager(app)
manager.add_command('db', MigrateCommand)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(128))
if __name__ == '__main__':
manager.run()
_
これは単純な遊びの例としてはうまく機能しますが、モデルが複数あるため、このスクリプトとアプリケーションコードを定義するスクリプトの両方でモデルを定義したくありません。したがって、2つの間で共有できるモデルファイルにそれらをプルしたいと思います。
User
クラスを_models.py
_に配置し、そこからUserをインポートすることで、これを実行しようとしています。残念ながら、それは_NameError: name 'db' is not defined
_をスローします。
私の質問は次のとおりです。
models.py
_でdb = SQLAlchemy(app)
を使用する必要がありますか?使用する場合、これは移行スクリプトとflaskアプリケーション自体の両方で使用できますか?models.py
_に入れることができない(または入れてはいけない)場合、db
を渡さずに、モデルを独自のファイルで利用するにはどうすればよいですか?このような小さなアプリケーションをモジュールに分割するのは難しいです。作成する2つのモジュールが相互にインポートする必要があり、循環依存関係が作成される場合が多いためです。
アプリファクトリ関数とすべての拡張機能の初期化の遅延を使用して、より大きなアプリケーションを適切に構造化する方法を確認することをお勧めします。これを行うサンプルアプリケーションは、私の本で取り上げられている Flasky アプリです。
とはいえ、アプリケーションを2つの部分に分割することは可能ですが、インポートステートメントを配置する場所に注意する必要があります。以下の例では、db
インスタンスとUser
モデルの作成をmodels.pyファイルに移動することにしました。
メインアプリケーションのモジュールは次のとおりです。
from flask import Flask
from flask.ext.script import Manager
from flask.ext.migrate import Migrate, MigrateCommand
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///app.db'
from models import db # <-- this needs to be placed after app is created
migrate = Migrate(app, db)
manager = Manager(app)
manager.add_command('db', MigrateCommand)
if __name__ == '__main__':
manager.run()
そしてここにmodels.pyがあります:
from __main__ import app
from flask.ext.sqlalchemy import SQLAlchemy
db = SQLAlchemy(app)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(128))
ここで、メインモジュールはapp
を作成し、その後でのみmodels.pyをインポートします。 models.pyがメインモジュールからapp
をインポートしようとすると、すでに作成されています。移動した場合from models import db
他のインポートを含むファイルの先頭に、このコードが壊れます。
ここにアイデアがあります。クラスを個別の.py
ファイルとして定義するパッケージmodel
を作成できます。たとえば、user.py
にはUser
クラスが含まれます。
__init__.py
ファイルでは、db
変数を定義できます。パッケージの外部でUser
オブジェクトに直接アクセスできるように、from user import User
ステートメントを含めることもできます。たとえば、import model
を使用してプログラム内の別の場所にmodel
パッケージをインポートしてから、model.User
を使用してUser
クラスを直接使用できます。
user.py
でdb
変数を直接使用するには、from ..model import db
ファイルで定義されたdb
変数をインポートする__init__.py
を使用します。