FlaskのSQLAlchemy—フラスコのドキュメント

提供:Dev Guides
< FlaskFlask/docs/1.0.x/patterns/sqlalchemy
移動先:案内検索

FlaskのSQLAlchemy

多くの人がデータベースアクセスに SQLAlchemy を好みます。 この場合、フラスコアプリケーション用のモジュールの代わりにパッケージを使用し、モデルを別のモジュール(より大きなアプリケーション)にドロップすることをお勧めします。 それは必須ではありませんが、それは非常に理にかなっています。

SQLAlchemyを使用する4つの非常に一般的な方法があります。 ここでそれぞれの概要を説明します。

Flask-SQLAlchemy拡張

SQLAlchemyは、一般的なデータベース抽象化レイヤーおよびオブジェクトリレーショナルマッパーであり、少しの構成作業が必要なため、それを処理するFlask拡張機能があります。 すぐに始めたい場合は、これをお勧めします。

Flask-SQLAlchemyPyPI からダウンロードできます。


宣言型

SQLAlchemyの宣言型拡張は、SQLAlchemyを使用する最新の方法です。 Djangoの動作と同様に、テーブルとモデルを一度に定義できます。 次のテキストに加えて、宣言型拡張機能に関する公式ドキュメントをお勧めします。

アプリケーションのdatabase.pyモジュールの例を次に示します。

from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy.ext.declarative import declarative_base

engine = create_engine('sqlite:////tmp/test.db', convert_unicode=True)
db_session = scoped_session(sessionmaker(autocommit=False,
                                         autoflush=False,
                                         bind=engine))
Base = declarative_base()
Base.query = db_session.query_property()

def init_db():
    # import all modules here that might define models so that
    # they will be registered properly on the metadata.  Otherwise
    # you will have to import them first before calling init_db()
    import yourapplication.models
    Base.metadata.create_all(bind=engine)

モデルを定義するには、上記のコードで作成された Base クラスをサブクラス化します。 なぜここでスレッドを気にする必要がないのか疑問に思っている場合(上記の g オブジェクトを使用したSQLite3の例のように):これは、SQLAlchemyがすでに [を使用してスレッドを処理しているためです。 X201X]。

アプリケーションで宣言的な方法でSQLAlchemyを使用するには、次のコードをアプリケーションモジュールに配置するだけです。 Flaskは、リクエストの終了時またはアプリケーションのシャットダウン時にデータベースセッションを自動的に削除します。

from yourapplication.database import db_session

@app.teardown_appcontext
def shutdown_session(exception=None):
    db_session.remove()

モデルの例を次に示します(たとえば、これをmodels.pyに入れます)。

from sqlalchemy import Column, Integer, String
from yourapplication.database import Base

class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    name = Column(String(50), unique=True)
    email = Column(String(120), unique=True)

    def __init__(self, name=None, email=None):
        self.name = name
        self.email = email

    def __repr__(self):
        return '<User %r>' % (self.name)

データベースを作成するには、 init_db 関数を使用できます。

>>> from yourapplication.database import init_db
>>> init_db()

次のようにデータベースにエントリを挿入できます。

>>> from yourapplication.database import db_session
>>> from yourapplication.models import User
>>> u = User('admin', 'admin@localhost')
>>> db_session.add(u)
>>> db_session.commit()

クエリも簡単です。

>>> User.query.all()
[<User u'admin'>]
>>> User.query.filter(User.name == 'admin').first()
<User u'admin'>

手動オブジェクトリレーショナルマッピング

手動オブジェクトリレーショナルマッピングには、上からの宣言型アプローチと比較して、いくつかの利点といくつかの欠点があります。 主な違いは、テーブルとクラスを別々に定義し、それらを一緒にマップすることです。 柔軟性はありますが、入力するのに少し時間がかかります。 一般に、これは宣言型アプローチのように機能するため、アプリケーションをパッケージ内の複数のモジュールに分割することも忘れないでください。

アプリケーションのdatabase.pyモジュールの例を次に示します。

from sqlalchemy import create_engine, MetaData
from sqlalchemy.orm import scoped_session, sessionmaker

engine = create_engine('sqlite:////tmp/test.db', convert_unicode=True)
metadata = MetaData()
db_session = scoped_session(sessionmaker(autocommit=False,
                                         autoflush=False,
                                         bind=engine))
def init_db():
    metadata.create_all(bind=engine)

宣言型アプローチと同様に、各要求またはアプリケーションコンテキストのシャットダウン後にセッションを閉じる必要があります。 これをアプリケーションモジュールに入れます。

from yourapplication.database import db_session

@app.teardown_appcontext
def shutdown_session(exception=None):
    db_session.remove()

これがテーブルとモデルの例です(これをmodels.pyに入れてください):

from sqlalchemy import Table, Column, Integer, String
from sqlalchemy.orm import mapper
from yourapplication.database import metadata, db_session

class User(object):
    query = db_session.query_property()

    def __init__(self, name=None, email=None):
        self.name = name
        self.email = email

    def __repr__(self):
        return '<User %r>' % (self.name)

users = Table('users', metadata,
    Column('id', Integer, primary_key=True),
    Column('name', String(50), unique=True),
    Column('email', String(120), unique=True)
)
mapper(User, users)

クエリと挿入は、上記の例とまったく同じように機能します。


SQL抽象化レイヤー

データベースシステム(およびSQL)の抽象化レイヤーを使用したいだけの場合は、基本的にエンジンのみが必要です。

from sqlalchemy import create_engine, MetaData, Table

engine = create_engine('sqlite:////tmp/test.db', convert_unicode=True)
metadata = MetaData(bind=engine)

次に、上記の例のようにコードでテーブルを宣言するか、テーブルを自動的にロードします。

from sqlalchemy import Table

users = Table('users', metadata, autoload=True)

データを挿入するには、 insert メソッドを使用できます。 トランザクションを使用できるように、最初に接続を取得する必要があります。

>>> con = engine.connect()
>>> con.execute(users.insert(), name='admin', email='admin@localhost')

SQLAlchemyは自動的にコミットします。

データベースにクエリを実行するには、エンジンを直接使用するか、接続を使用します。

>>> users.select(users.c.id == 1).execute().first()
(1, u'admin', u'admin@localhost')

これらの結果もdictのようなタプルです。

>>> r = users.select(users.c.id == 1).execute().first()
>>> r['name']
u'admin'

SQLステートメントの文字列をexecute()メソッドに渡すこともできます。

>>> engine.execute('select * from users where id = :1', [1]).first()
(1, u'admin', u'admin@localhost')

SQLAlchemyの詳細については、 Webサイトにアクセスしてください。