1

エンド ユーザーから提供された資格情報を使用してデータベースにログインする必要がある Web アプリケーションを開発しています。アプリケーション自体にはデータベースへのログインがありません。

問題は、ユーザー セッションごとに1 つの接続を作成する方法です。

1 つのアプローチは次のとおりです。

  1. ユーザーの資格情報を要求する
  2. 認証情報が db バックエンドに対して有効かどうかを確認する
  3. 資格情報をセッション レベルの変数に保存する

このアプローチの問題は、そのセッションの後続の各リクエストにあります。新しい接続を作成する必要があります。これにより、サーバーへの最大接続数がすぐに使い果たされます。

OracleでFlaskを使用しています。

Flask には、gリクエスト スコープのオブジェクトを格納するオブジェクトがあります。ただし、このスニペットは機能しません。

app = Flask(__name__)
app.config.from_object(__name__)

def login_required(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if g.db is None:
            return redirect(url_for('login', next=request.url))
        return f(*args, **kwargs)
     return decorated_function

class LoginForm(Form):
    username = TextField('Username', [validators.Length(min=4, max=25)])
    password = PasswordField('Password', [validators.Required()])

@app.route('/app', methods=['GET','POST'])
@login_required
def index():
    return 'Index'

@app.route('/', methods=['GET','POST'])
def login():
    form = LoginForm(request.form)
    if request.method == 'POST':
        if form.validate():
           try:
               dsn = cx_Oracle.makedsn(app.config['DB_HOST'],
                                       app.config['DB_PORT'], app.config['DB_SID'])
               g.db = cx_Oracle.connect(form.username.data,
                                        form.password.data, dsn)
           except cx_Oracle.DatabaseError as e:
               flash(unicode(e), 'error')
               return render_template('login.html', form=form)
            return redirect(url_for('index'))
        else:
            return render_template('login.html', form=form)
    else:
        return render_template('login.html', form=form)

AttributeError: '_RequestGlobals' object has no attribute 'db'

4

2 に答える 2

1

このスニペットが機能しない理由は、この行です

    if g.db is None:

g に属さない属性にアクセスしています。次のコード行を追加します。

    @app.before_request
    def before_request():
         g.db = None

before_request() でマークされた関数は、リクエストの前に呼び出され、引数を渡しません。

コネクションプーリングについて

Python にはSQLAlchemyと呼ばれる ORM と SQL Toolkit があり、接続プールを自動的に行います。また、flask の g オブジェクトを管理し、より安全な準備済み SQL ステートメントを作成します。

次の 2 つの部分があります。

    1. Core which is a SQL abstraction toolkit.
    2. ORM is an optional package which builds on top of Core.

したがって、ORM を使用したくない場合は、その Core をそのまま使用してください。ここで確認してください。

cx_Oracle を介して Oracle をサポートし、SQLAlchemy Docs hereに記載されているように設定できます。

Python での接続プーリングに関する詳細については、この質問を確認してください。

于 2012-06-08T09:08:35.820 に答える
0

接続プーリングを実装する必要があるようです。要求ごとに新しい接続を要求する (まったくスケーリングしない) 代わりに、必要な属性を持つプールから接続をチェックアウトするだけです。適切な接続が利用できない場合、プールは新しい接続を作成します。もちろん、プールは、しばらく使用されていない接続を閉じる際に、反対のケースも処理する必要があります。

そのようなプールが python で利用できるかどうかを確認することをお勧めします。Java oracle では、UCP でこれをサポートし、OCI ではセッション プールでこれをサポートします。私が間違っていなければ、.Net 用の接続プールも提供されています。

于 2012-06-08T02:09:33.943 に答える