【问题标题】:Flask.g database connection - RuntimeError: Working outside of application contextFlask.g 数据库连接 - RuntimeError:在应用程序上下文之外工作
【发布时间】:2020-08-12 10:10:18
【问题描述】:

我正在尝试将数据库连接分配给Flask.g,以便在我的整个应用程序中都可以访问它。

但是我遇到了错误:

RuntimeError: Working outside of application context.

文件app/database/__init__.py

from flask import current_app, g
from .connection import Connection


class Database:
    def __init__(self, app):
        if 'db' not in g:
            g.db = Connection(app)

    def get(self):
        if 'db' in g:
            return g.db
        else:
            g.db = Connection(current_app)
            return g.db

文件app/database/connection.py

import psycopg2
import psycopg2.extras
from ..error import DatabaseConnectionFailed


class Connection:
    connection = None
    cursor = None

    def __init__(self, app):
        self.connect(app)

    def connect(self, app):
        try:
            self.connection = psycopg2.connect(
                user=app.config['APP_DB_PSQL_USER'],
                password=app.config['APP_DB_PSQL_PASSWORD'],
                host=app.config['APP_DB_PSQL_HOST'],
                port=app.config['APP_DB_PSQL_PORT'],
                database=app.config['APP_DB_PSQL_DATABASE'],
                application_name=self.client(app)
            )
            self.connection.autocommit = True
            self.cursor = self.connection.cursor(cursor_factory=psycopg2.extras.DictCursor)
        except (psycopg2.NotSupportedError, psycopg2.ProgrammingError, psycopg2.DataError, psycopg2.IntegrityError, psycopg2.InternalError, psycopg2.OperationalError, psycopg2.DatabaseError, Exception) as e:
            raise DatabaseConnectionFailed()
        else:
            logging.warning('Connected successfully to database!')

app/__init__.py

from flask import Flask, jsonify, request, redirect  
from .database import Database  


def create_app(settings):
    app = Flask(__name__)     
    app.config.from_object(settings)
    
    Database(app)

【问题讨论】:

    标签: python flask


    【解决方案1】:

    当您在应用程序工厂中创建 Database() 对象时,您将添加到 g.db 的连接,正如您所指出的。但是g 绑定到当前应用程序上下文。这是一个问题,因为...

    根据需要创建和销毁应用程序上下文。当一个 Flask 应用程序开始处理请求,它推送一个应用程序 上下文和请求上下文。当请求结束时,它会弹出 请求上下文然后是应用程序上下文。通常,一个 应用程序上下文将与请求具有相同的生命周期。

    https://flask.palletsprojects.com/en/1.1.x/appcontext/#lifetime-of-the-context

    与其将连接存储在g 中,不如将其存储在可从应用的其他部分导入的python 变量中。

    在名为database.py 的文件中创建您的Database() 对象,并将其存储在例如变量中。添加然后将其导入您的应用程序工厂并在工厂中调用connect

    然后在您需要数据库的任何地方,从database.py 导入它。

    还可以查看Flask-SQLAlchemy 项目,因为它是一种更好的方式来做你想做的事情。

    【讨论】:

    • 当 uWSGI 创建一个工作线程时,我想启动与数据库的连接并在工作线程的整个生命周期内保持打开状态。我怎样才能做到这一点?我需要在create_app() 之外创建连接吗?我不想使用 SQLAlchemy。
    猜你喜欢
    • 2015-10-05
    • 1970-01-01
    • 2021-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-30
    • 2021-02-06
    • 1970-01-01
    相关资源
    最近更新 更多