【Python】Flaskのグローバル変数「g」のエラー回避

Flask

はじめに

しげっち
しげっち

PythonのWEBフレームワークであるFlaskにて、グローバル変数のgがエラーになる現象からなかなか抜け出せなかった話をするよ!

にゃーすけ
にゃーすけ

gちゃ〜ん!!

しげっち
しげっち

おじいちゃんみたいに呼ばないの。

Flask学習におすすめの本を紹介します。
⇨【Python】Flask入門におすすめの本 3選

グローバル変数「g」を使用するとエラーになる

import sqlite3
from flask import Flask, g

def get_db():
    if 'db' not in g:
        g.db = sqlite3.connect('TestDB.db')
    return g.db

app = Flask(__name__)
con = get_db()

上記サンプルのget_dbメソッドでは「g」にdbがなければSQLiteのコネクションを作成しています。

実行すると、if ‘db’ not in g:の部分でRuntimeErrorが発生します。
エラーの内容を見るとWorking outside of application context.と表示されています。

結論を言うと、「g」はアプリケーションコンテキストに属する変数のようです。

アプリケーションコンテキストはFlaskのインスタンスが作成されるタイミングで同時に作成されます。
上記サンプルだと「g」に属するアプリケーションコンテキストが指定されていないためエラーになります。

エラーの対処方法

エラーを回避するため、サンプルを修正してみましょう。

import sqlite3
from flask import Flask, g

def get_db():
    with app.app_context():
        if 'db' not in g:
            g.db = sqlite3.connect('TestDB.db')
        return g.db

app = Flask(__name__)
con = get_db()

変更した箇所は、with app.app_context():の部分です。
これで、「g」はFlaskのインスタンスであるappのアプリケーションコンテキスト(app_context)に属するものとして動作し、エラーを回避できます。

Flaskのデコレータが適用されたメソッド内ではエラーにならない

まずはサンプルを見てみましょう。

import sqlite3
from flask import Flask, render_template, g

def get_db():
    if 'db' not in g:
         g.db = sqlite3.connect('TestDB.db')
    return g.db

app = Flask(__name__)

@app.route('/')
def index():
    con = get_db()
    return render_template('index.html')

if __name__ == '__main__':
    app.run('127.0.0.1', 5000, debug=true)




このサンプルではindexメソッド内でget_dbを記載しています。
get_db内では明示的にアプリケーションコンテキストを指定していませんが、これを実行してもエラーにはなりません。
これは、Flaskのルーティングするためのデコレータ(上記サンプルでは@app.route(‘/’))にて、インスタンスを指定しているからです。

デコレータについては下記の記事を参照ください。

まとめ

Flaskのグローバル変数「g」のエラー回避方法について解説しました。

  • Flaskのグローバル変数「g」を使用するには、明示的にFlaskインスタンスのアプリケーションコンテキストを指定する必要がある。
  • Flaskのルーティング用デコレータが記載されているメソッド内で使用する場合は、デコレータでFlaskインスタンスが指定されるので、エラーにならない。
しげっち
しげっち

最後まで読んでいただき、ありがとうございます。

Flask学習におすすめの本を紹介します。
⇨【Python】Flask入門におすすめの本 3選

タイトルとURLをコピーしました