2012-06-07 166 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连接池的更多讨论。