2012-06-07 165 views
1

我正在開發一個Web應用程序,需要使用由最終用戶提供的憑據登錄到數據庫;應用程序本身沒有登錄數據庫。序列化跨數據庫連接的數據庫連接

問題是如何創建一個連接用戶會話

一種方法是:

  1. 請求用戶的憑據
  2. 檢查證書有效防止DB後端
  3. 存儲憑證在會話級變量

問題的這種做法,隨後對該屆會議的每次請求;你需要創建一個新的連接;這將很快耗盡與服務器的最大連接。

我正在使用Flask與Oracle。

在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'

回答

0

聽起來像是你需要實現連接池。而不是爲每個請求(它根本沒有擴展)請求一個新的連接,只需從池中檢出具有所需屬性的連接即可。如果沒有合適的連接可用,池將創建一個新的連接。當然,在關閉一段時間未使用的連接時,池也需要處理相反的情況。

您可能想要檢查這樣的池是否可用於python。對於java,oracle支持UCP和OCI與會話池。如果我沒有錯誤的連接池甚至提供.Net。

+0

cx_Oracle確實提供了連接池,但是,要啓動我需要用戶憑據的池。因此,一旦我擁有了游泳池,我將如何在整個請求中請求來自該游泳池的連接? –

1

爲什麼這個片斷是不工作的原因是該行

if g.db is None: 

您正在訪問不屬於G的屬性。添加以下代碼行:

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

用before_request()標記的函數在請求前被調用並且沒有參數傳遞。

關於連接池

有一個ORM和SQL工具包在Python這確實連接自動爲您彙集稱爲SQLAlchemy。 它還管理燒瓶的g對象,並創建準備好的SQL語句,這些語句更加安全。

它有兩個部分:

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

所以,如果你不想使用ORM然後只需使用其核心與所有完整的功能。 檢查here

它通過cx_Oracle支持Oracle和它可以被設置爲在SQLAlchemy的文檔here提及。

查看這個question關於python連接池的更多討論。