こんにちは、habrauser。
少し前、友人と私はVersumプロジェクトの一環として小さなテキストグッズを作り始めました。 この記事では、私たちが直面しなければならなかった問題と、どのソリューションを選択したかについてお話したいと思います。
Python、特にFlaskマイクロフレームワークを使用します。
Flaskをインストールする
プロセスは非常に簡単です
ピップインストールフラスコ pip install sqlalchemy pip install flask-sqlalchemy pip install alembic
私に出会ったマニュアルでは、 sqlalchemy-migrateが移行に使用されていますが、それは少しひどいようです。 sqlalchemyバージョンに依存しています 。つまり、移行を使用するには、相互にバージョンを明確に選択する必要があります。 さらに、 sqlalchemy-migrate ページには次のように記載されています。
SQLAlchemyでプロジェクトを開始し、データスキーマの移行が必要な場合は、Alembicを使用します
罪は助言を受けません。
cd〜 mkdirフラスコ cdフラスコ alembic init alembic mkdir app_name
そして次のポイントに進みます。
アプリケーションのスケルトン
簡単な「Hello、World!」を作成するには、公式Webサイトに良いマニュアルがあります 。 しかし、サンドボックスで十分にプレイした後、私たちは将来のアプリケーションのスケルトンを収集し始め、いわば最初の問題に直面しました。 Djangoがアプリケーション構造を課し、startprojectとstartappの後に自動的に生成される場合、Flaskは完全な自由を与えます。 これを「問題」と見なす価値があるかどうかはわかりませんが、どこを掘るかわからないときは悲しくなり、手が落ちます。
しかし、公式教科書の長い瞑想の後、githubのリポジトリ(特に、「flask skeleton」の検索結果)を詳しく調べた後、 一連の記事(著者Miguel Grinberg)を読んだ後、いくつかの洞察と安心がもたらされました。
最終的に、アプリケーションのスケルトンは次のとおりです。
〜/フラスコ |-/ alembic |-/ app_name | |-/静的 | | |-/ css | | |-/ js | | |-/ / img | |-/テンプレート | | |-index.html | |-__init__.py | |-config.py | |-models.py | |-views.py |-alembic.ini |-README.md |-requirements.txt |-runserver.py
順番に行きましょう、flaskはプロジェクトのルートフォルダー、gitはここで初期化され、仮想環境はここで作成されます。一般に、devサーバーの起動ファイルrunserver.pyを含むプロジェクトに関連するすべてのものがあります。 それは非常に簡単で、ローカルマシンでアプリケーションを実行するために使用します。
#!/usr/bin/env python from app_name import app if __name__ == '__main__': if app.debug: app.run(debug=True) else: app.run(host='0.0.0.0')
アプリケーションとそのモジュールの初期化を含むすべての基本事項は、 __ init__.pyで発生します
import os FLASK_APP_DIR = os.path.dirname(os.path.abspath(__file__)) # Flask from flask import Flask app = Flask(__name__) # Config app.config.from_object('app_name.config.DevelopmentConfig') # ProductionConfig #app.config.from_object('app_name.config.ProductionConfig') # Connect to database with sqlalchemy. from flask.ext.sqlalchemy import SQLAlchemy db = SQLAlchemy(app) # Business Logic # http://flask.pocoo.org/docs/patterns/packages/ # http://flask.pocoo.org/docs/blueprints/ from app_name.views import frontend app.register_blueprint(frontend)
config.py自体は次のようになります。
class Config(object): SECRET_KEY = 'some_secret' SITE_NAME = 'app_name.ru' SQLALCHEMY_DATABASE_URI = 'mysql://user:pass@localhost/tabe_name?charset=utf8' class ProductionConfig(Config): DEBUG = False TESTING = False class TestConfig(Config): DEBUG = False TESTING = True class DevelopmentConfig(Config): '''Use "if app.debug" anywhere in your code, that code will run in development code.''' DEBUG = True TESTING = True
ここで、アプリケーションのすべての場所で使用されるアプリオブジェクトに移動します(PYTHONPATHにフラスコフォルダーを追加した場合)。
app_nameインポートアプリから
この場合、アプリケーションが機能するために必要なものはすべて接続されています。
alembicを初期化するとき、 alembic.iniもrootにありますが、それに触れる必要はありません。 アプリケーションと統合するには、 alembicフォルダー内にあるenv.pyファイルにアクセスする必要があります。
行の後に#target_metadata = mymodel.Base.metadataを追加する必要があります。
# target_metadata = mymodel.Base.metadata from app_name import db target_metadata = db.metadata
run_migrations_onlineを書き換えます :
def run_migrations_online(): """Run migrations in 'online' mode. In this scenario we need to create an Engine and associate a connection with the context. """ alembic_config = config.get_section(config.config_ini_section) from app_name import app alembic_config['sqlalchemy.url'] = app.config['SQLALCHEMY_DATABASE_URI'] engine = engine_from_config( alembic_config, prefix='sqlalchemy.', poolclass=pool.NullPool) connection = engine.connect() context.configure( connection=connection, target_metadata=target_metadata ) try: with context.begin_transaction(): context.run_migrations() finally: connection.close()
これで、 alembicとアプリケーションの統合が完了しました。 自動移行の場合、次を使用します。
アレンビックリビジョン--autogenerate -m 'some text'
この場合、 hashcode_some_text.pyという形式の移行ファイルがバージョンフォルダーに作成されます。 それらを調べることが望ましく、時には必要な場合もあります。 開発者自身によると、alembicはテーブルとフィールドの名前変更を理解せず、キーの作成も不十分です。
移行を適用するには、次のコマンドを使用します。
アレンビックアップグレードヘッド
config.pyファイルの最後の行は、ビジネスロジックが格納されているviews.pyをキャッチし ます 。 開始する最小セットは次のとおりです。
from app_name import app, db from flask import Blueprint, request, render_template frontend = Blueprint('frontend', __name__) # 404 page not found "route" @app.errorhandler(404) def not_found(error): title = "404 Page not found" return render_template('404.html', title=title), 404 # 500 server error "route" @app.errorhandler(500) def server_error(error): title = "500 Server Error" db.session.rollback() return render_template('500.html', title=title), 500 # general routes @frontend.route('/') def index(): return render_template( 'index.html', title = u' ', )
初めに、gebugを無効にした後に機能するエラーのハンドラーが追加されました。 一般に、これは同じ「Hello、World!」ですが、拡張バージョンでは同じです。
models.pyファイルにはモデルが保存されますが、現在は空です。 それぞれstaticおよびtemplatesにあるstaticsおよびtemplatesを使用すると、すべてが明確に見えます。
サーバーで実行する
nginxとuwsgiを使用してサーバーを起動した後、クラッシュしたときに美しいデベッジャーが表示されないことが判明しました。 runserver.pyを介してサーバーを起動すると、すべてが正常に実行され、デバッガーが配置されます。
uwsgiデーモンはログに詳細なエラー情報を書き込むため、すべてがそれほど悪いわけではありません。 バグはかなり古く、少なくともstackoverflowに関する1年の質問がありました 。 これはuwsgi自体またはnginxとの友情の問題のようですが、この誤解を解決できませんでした。 ローカルマシンのデバッガーとメールのエラーメッセージに満足しています。
この記事が、Flaskで初めてアプリケーションを作成するユーザーの時間を少し節約するのに役立つことを願っています。