sql >> データベース >  >> RDS >> Database

例によるフラスコ– Postgres、SQLAlchemy、およびAlembicのセットアップ

    このパートでは、ワードカウントの結果を保存するPostgresデータベースと、データベースの移行を処理するSQLAlchemy、オブジェクトリレーショナルマッパー、およびAlembicをセットアップします。

    無料ボーナス: ここをクリックして、FlaskWebアプリの構築方法を段階的に説明する無料のFlask+Pythonビデオチュートリアルにアクセスしてください。

    更新:

    • 2020年2月9日:Pythonバージョン3.8.1と、最新バージョンのPsycopg2、Flask-SQLAlchemy、Flask-Migrateにアップグレードしました。詳細については、以下を参照してください。 Flask-Migrate内部インターフェースの変更により、Flask-Scriptを明示的にインストールして使用します。
    • 2016年3月22日:Pythonバージョン3.5.1にアップグレードされ、最新バージョンのPsycopg2、Flask-SQLAlchemy、Flask-Migrateにアップグレードされました。詳細については、以下をご覧ください。
    • 2015年2月22日:Python3のサポートが追加されました。

    注意:これが私たちが構築しているものです-指定されたURLからのテキストに基づいて単語と頻度のペアを計算するFlaskアプリ。

    1. パート1:ローカル開発環境をセットアップしてから、ステージング環境と本番環境の両方をHerokuにデプロイします。
    2. パート2:移行を処理するためにSQLAlchemyおよびAlembicとともにPostgreSQLデータベースをセットアップします。 (現在
    3. パート3:バックエンドロジックを追加して、リクエスト、BeautifulSoup、Natural Language Toolkit(NLTK)ライブラリを使用してウェブページから単語数を取得して処理します。
    4. パート4:テキスト処理を処理するためのRedisタスクキューを実装します。
    5. パート5:フロントエンドにAngularを設定して、バックエンドを継続的にポーリングし、リクエストの処理が完了したかどうかを確認します。
    6. パート6:Herokuのステージングサーバーにプッシュします-Redisをセットアップし、1つのDynoで2つのプロセス(Webとワーカー)を実行する方法を詳しく説明します。
    7. パート7:フロントエンドを更新してユーザーフレンドリーにします。
    8. パート8:JavaScriptとD3を使用して度数分布図を表示するカスタムAngularディレクティブを作成します。

    <マーク>コードが必要ですか?リポジトリから取得します。


    インストール要件

    このパートで使用されるツール:

    • PostgreSQL(11.6)
    • Psycopg2(2.8.4)-Postgres用のPythonアダプター
    • Flask-SQLAlchemy(2.4.1)-SQLAlchemyサポートを提供するFlask拡張機能
    • Flask-Migrate(2.5.2)-Alembicを介したSQLAlchemyデータベースの移行をサポートする拡張機能

    開始するには、Postgresをローカルコンピュータにインストールします(まだインストールしていない場合)。 HerokuはPostgresを使用しているため、同じデータベースでローカルに開発することをお勧めします。 Postgresがインストールされていない場合、Postgres.appはMacOSXユーザーが簡単に起動して実行できる方法です。詳細については、ダウンロードページを参照してください。

    Postgresをインストールして実行したら、wordcount_devというデータベースを作成します。 ローカル開発データベースとして使用するには:

    $ psql
    # create database wordcount_dev;
    CREATE DATABASE
    # \q
    

    Flaskアプリ内で新しく作成したデータベースを使用するには、いくつかのものをインストールする必要があります。

    $ cd flask-by-example
    

    cd ディレクトリにアクセスすると、仮想環境がアクティブになり、.envにある環境変数が設定されます。 パート1で設定したautoenv経由のファイル。

    $ python -m pip install psycopg2==2.8.4 Flask-SQLAlchemy===2.4.1 Flask-Migrate==2.5.2
    $ python -m pip freeze > requirements.txt
    

    OS Xを使用していて、psycopg2のインストールに問題がある場合は、このStackOverflowの記事をご覧ください。

    psycopg2-binaryをインストールする必要がある場合があります psycopg2の代わりに インストールが失敗した場合。



    構成の更新

    SQLALCHEMY_DATABASE_URIを追加します Config()へのフィールド config.pyのクラス 開発(ローカル)、ステージング、および本番環境で新しく作成されたデータベースを使用するようにアプリを設定するファイル:

    import os
    
    class Config(object):
        ...
        SQLALCHEMY_DATABASE_URI = os.environ['DATABASE_URL']
    

    config.py ファイルは次のようになります:

    import os
    basedir = os.path.abspath(os.path.dirname(__file__))
    
    
    class Config(object):
        DEBUG = False
        TESTING = False
        CSRF_ENABLED = True
        SECRET_KEY = 'this-really-needs-to-be-changed'
        SQLALCHEMY_DATABASE_URI = os.environ['DATABASE_URL']
    
    
    class ProductionConfig(Config):
        DEBUG = False
    
    
    class StagingConfig(Config):
        DEVELOPMENT = True
        DEBUG = True
    
    
    class DevelopmentConfig(Config):
        DEVELOPMENT = True
        DEBUG = True
    
    
    class TestingConfig(Config):
        TESTING = True
    

    これで、構成がアプリに読み込まれると、適切なデータベースもアプリに接続されます。

    前回の投稿で環境変数を追加したのと同様に、DATABASE_URLを追加します。 変数。ターミナルでこれを実行します:

    $ export DATABASE_URL="postgresql:///wordcount_dev"
    

    次に、その行を .envに追加します ファイル。

    app.py ファイルはSQLAlchemyをインポートし、データベースに接続します:

    from flask import Flask
    from flask_sqlalchemy import SQLAlchemy
    import os
    
    
    app = Flask(__name__)
    app.config.from_object(os.environ['APP_SETTINGS'])
    app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
    db = SQLAlchemy(app)
    
    from models import Result
    
    
    @app.route('/')
    def hello():
        return "Hello World!"
    
    
    @app.route('/<name>')
    def hello_name(name):
        return "Hello {}!".format(name)
    
    
    if __name__ == '__main__':
        app.run()
    


    データモデル

    models.py を追加して、基本モデルを設定します ファイル:

    from app import db
    from sqlalchemy.dialects.postgresql import JSON
    
    
    class Result(db.Model):
        __tablename__ = 'results'
    
        id = db.Column(db.Integer, primary_key=True)
        url = db.Column(db.String())
        result_all = db.Column(JSON)
        result_no_stop_words = db.Column(JSON)
    
        def __init__(self, url, result_all, result_no_stop_words):
            self.url = url
            self.result_all = result_all
            self.result_no_stop_words = result_no_stop_words
    
        def __repr__(self):
            return '<id {}>'.format(self.id)
    

    ここでは、単語数の結果を保存するためのテーブルを作成しました。

    まず、 app.pyで作成したデータベース接続をインポートします。 ファイルとSQLAlchemyのPostgreSQL方言からのJSON。 JSON列はPostgresにとってかなり新しいものであり、SQLAlchemyでサポートされているすべてのデータベースで使用できるわけではないため、具体的にインポートする必要があります。

    次に、Result()を作成しました クラスにresultsのテーブル名を割り当てました 。次に、結果のために保存する属性を設定します-

    • id 保存した結果の
    • url からの単語を数えた
    • カウントした単語の完全なリスト
    • カウントした単語のリストからストップワードを差し引いたもの(これについては後で詳しく説明します)

    次に、__init__()を作成しました 新しい結果を最初に作成するときに実行され、最後に__repr__()が実行されるメソッド オブジェクトを照会するときにオブジェクトを表すメソッド。



    ローカル移行

    Flask-Migrateの一部であるAlembicを使用して、データベースの移行を管理し、データベースのスキーマを更新します。

    注: Flask-MigrateはFlasksの新しいCLIツールを利用します。ただし、この記事では、Flask-Migrateが以前使用していたFlask-Scriptが提供するインターフェイスを使用しています。使用するには、次の方法でインストールする必要があります。

    $ python -m pip install Flask-Script==2.0.6
    $ python -m pip freeze > requirements.txt
    

    manage.pyという名前の新しいファイルを作成します :

    import os
    from flask_script import Manager
    from flask_migrate import Migrate, MigrateCommand
    
    from app import app, db
    
    
    app.config.from_object(os.environ['APP_SETTINGS'])
    
    migrate = Migrate(app, db)
    manager = Manager(app)
    
    manager.add_command('db', MigrateCommand)
    
    
    if __name__ == '__main__':
        manager.run()
    

    Flask-Migrateを使用するために、Managerをインポートしました Migrateも同様です およびMigrateCommand manage.pyに ファイル。 appもインポートしました およびdb そのため、スクリプト内からそれらにアクセスできます。

    まず、環境変数に基づいて環境を取得するように構成を設定し、appを使用して移行インスタンスを作成しました。 およびdb 引数として、managerを設定します Managerを初期化するコマンド 私たちのアプリのインスタンス。最後に、dbを追加しました managerへのコマンド コマンドラインから移行を実行できるようにします。

    移行を実行するには、Alembicを初期化します。

    $ python manage.py db init
      Creating directory /flask-by-example/migrations ... done
      Creating directory /flask-by-example/migrations/versions ... done
      Generating /flask-by-example/migrations/alembic.ini ... done
      Generating /flask-by-example/migrations/env.py ... done
      Generating /flask-by-example/migrations/README ... done
      Generating /flask-by-example/migrations/script.py.mako ... done
      Please edit configuration/connection/logging settings in
      '/flask-by-example/migrations/alembic.ini' before proceeding.
    

    データベースの初期化を実行すると、プロジェクトに「migrations」という新しいフォルダが表示されます。これは、Alembicがプロジェクトに対して移行を実行するために必要なセットアップを保持します。 「migrations」の中には、「versions」というフォルダがあり、作成時に移行スクリプトが含まれていることがわかります。

    migrateを実行して、最初の移行を作成しましょう コマンド。

    $ python manage.py db migrate
      INFO  [alembic.runtime.migration] Context impl PostgresqlImpl.
      INFO  [alembic.runtime.migration] Will assume transactional DDL.
      INFO  [alembic.autogenerate.compare] Detected added table 'results'
        Generating /flask-by-example/migrations/versions/63dba2060f71_.py
        ... done
    

    これで、「バージョン」フォルダに移行ファイルがあることに気付くでしょう。このファイルは、モデルに基づいてAlembicによって自動生成されます。このファイルを自分で生成(または編集)することができます。ただし、ほとんどの場合、自動生成されたファイルで十分です。

    次に、db upgradeを使用してデータベースにアップグレードを適用します。 コマンド:

    $ python manage.py db upgrade
      INFO  [alembic.runtime.migration] Context impl PostgresqlImpl.
      INFO  [alembic.runtime.migration] Will assume transactional DDL.
      INFO  [alembic.runtime.migration] Running upgrade  -> 63dba2060f71, empty message
    

    これで、データベースをアプリで使用できるようになりました:

    $ psql
    # \c wordcount_dev
    You are now connected to database "wordcount_dev" as user "michaelherman".
    # \dt
    
                    List of relations
     Schema |      Name       | Type  |     Owner
    --------+-----------------+-------+---------------
     public | alembic_version | table | michaelherman
     public | results         | table | michaelherman
    (2 rows)
    
    # \d results
                                         Table "public.results"
            Column        |       Type        |                      Modifiers
    ----------------------+-------------------+------------------------------------------------------
     id                   | integer           | not null default nextval('results_id_seq'::regclass)
     url                  | character varying |
     result_all           | json              |
     result_no_stop_words | json              |
    Indexes:
        "results_pkey" PRIMARY KEY, btree (id)
    


    リモート移行

    最後に、Herokuのデータベースに移行を適用しましょう。ただし、最初に、ステージングデータベースと本番データベースの詳細を config.pyに追加する必要があります。 ファイル。

    ステージングサーバーにデータベースが設定されているかどうかを確認するには、次のコマンドを実行します。

    $ heroku config --app wordcount-stage
    === wordcount-stage Config Vars
    APP_SETTINGS: config.StagingConfig
    

    必ずwordcount-stageを置き換えてください ステージングアプリの名前で。

    データベース環境変数が表示されないため、Postgresアドオンをステージングサーバーに追加する必要があります。これを行うには、次のコマンドを実行します。

    $ heroku addons:create heroku-postgresql:hobby-dev --app wordcount-stage
      Creating postgresql-cubic-86416... done, (free)
      Adding postgresql-cubic-86416 to wordcount-stage... done
      Setting DATABASE_URL and restarting wordcount-stage... done, v8
      Database has been created and is available
       ! This database is empty. If upgrading, you can transfer
       ! data from another database with pg:copy
      Use `heroku addons:docs heroku-postgresql` to view documentation.
    

    hobby-dev HerokuPostgresアドオンの無料利用枠です。

    ここで、heroku config --app wordcount-stageを実行すると ここでも、データベースの接続設定が表示されます。

    === wordcount-stage Config Vars
    APP_SETTINGS: config.StagingConfig
    DATABASE_URL: postgres://azrqiefezenfrg:Zti5fjSyeyFgoc-U-yXnPrXHQv@ec2-54-225-151-64.compute-1.amazonaws.com:5432/d2kio2ubc804p7
    

    次に、gitに加えた変更をコミットして、ステージングサーバーにプッシュする必要があります。

    $ git push stage master
    

    heroku runを使用して、ステージングデータベースを移行するために作成した移行を実行します コマンド:

    $ heroku run python manage.py db upgrade --app wordcount-stage
      Running python manage.py db upgrade on wordcount-stage... up, run.5677
      INFO  [alembic.runtime.migration] Context impl PostgresqlImpl.
      INFO  [alembic.runtime.migration] Will assume transactional DDL.
      INFO  [alembic.runtime.migration] Running upgrade  -> 63dba2060f71, empty message
    

    upgradeのみを実行したことに注目してください 、initではありません またはmigrate 以前のようなコマンド。移行ファイルはすでに設定されており、準備ができています。 Herokuデータベースに対して適用する必要があります。

    生産についても同じことをしましょう。

    1. ステージングの場合と同じように、Herokuで本番アプリのデータベースを設定します。heroku addons:create heroku-postgresql:hobby-dev --app wordcount-pro
    2. 本番サイトに変更をプッシュします:git push pro master 構成ファイルに変更を加える必要がないことに注意してください。これは、新しく作成されたDATABASE_URLに基づいてデータベースを設定します。 環境変数。
    3. 移行を適用します:heroku run python manage.py db upgrade --app wordcount-pro

    これで、ステージングサイトと本番サイトの両方でデータベースがセットアップされ、移行され、準備が整いました。

    本番データベースに新しい移行を適用すると、ダウンタイムが発生する可能性があります。これが問題になる場合は、「フォロワー」(一般にスレーブと呼ばれる)データベースを追加することでデータベースレプリケーションを設定できます。詳細については、Herokuの公式ドキュメントをご覧ください。



    結論

    パート2は以上です。Flaskをさらに深く掘り下げたい場合は、付属のビデオシリーズをご覧ください:

    無料ボーナス: ここをクリックして、FlaskWebアプリの構築方法を段階的に説明する無料のFlask+Pythonビデオチュートリアルにアクセスしてください。

    パート3では、単語カウント機能を構築し、それをタスクキューに送信して、長時間実行される単語カウント処理を処理します。

    またね。乾杯!

    これは、StartupEdmontonの共同創設者であるCamLinkeとRealPythonの人々とのコラボレーション作品です。



    1. テーブルの列名をどのように返しますか?

    2. MariaDBとTableauを使い始めるための5つの簡単なステップ

    3. データベースをPythonに接続する方法

    4. SQLServerデータベースのCPU使用統計