2017-09-17 36 views
0

我为每个执行查询的函数添加了一个db.session.close()。查看错误还显示其他人有这个问题,因为与S3失去联系。在本地它工作得很好。但是运行相同与mod_wsgi的Ubuntu的服务器上的Apache2显示以下错误:Boto3显示ConnectionReset错误

185.27.213.237 - - [17/Sep/2017 16:31:34] "GET/HTTP/1.1" 200 - 
185.27.213.237 - - [17/Sep/2017 16:31:39] "POST/HTTP/1.1" 302 - 
('Connection aborted.', ConnectionResetError(104, 'Connection reset by peer')) 
185.27.213.237 - - [17/Sep/2017 16:31:50] "GET /space/user HTTP/1.1" 200 - 

从Apache日志:

[wsgi:error] [pid 1456:tid 139792612300544] ('Connection aborted.', ConnectionResetError(104, 'Connection reset by peer')) 

第一行是我打开登录路由。使用正确的凭据登录后,将显示302错误。在下面我张贴我的登录路线和成功登录后重定向到的网站。我使用sqlite3,因为我只有几个用户。

#Login 
@app.route('/', methods=['GET', 'POST']) 
def index(): 
    form = LoginForm() 

    try: 
     if form.validate_on_submit(): 
      user = User.query.filter_by(username=form.username.data).first() 
      if user: 
       if bcrypt.check_password_hash(user.password, form.password.data): 
        login_user(user, remember=False) 
        return redirect(url_for('showspace', spacename=user.username)) 
      return render_template('login.html', form=form, ermsg="Invalid credentials") 
     return render_template('login.html', form=form) 
    except Exception as ermsg: 
     db.session.rollback() 
     print(ermsg) 
     return redirect(url_for('index')) 
    finally: 
     db.session.close() 

#Dashboard new 
@app.route('/space/<spacename>', methods=['GET', 'POST']) 
@login_required 
def showspace(spacename): 
    try: 
     selectedspace=spacename 
     spacelist = Space.query.filter(Space.owner.any(id=current_user.id)).all() 
     hasaccess = User.query.join(User.spaces).filter(User.username==current_user.username, Space.name==selectedspace).first() 
     if hasaccess != None: 
      conn = boto3.resource('s3') 
      mybucket = conn.Bucket(selectedspace) 
      return render_template('dashboard.html', spaces=spacelist, filelist=mybucket.objects.all(), name=current_user.username, selectedspace=selectedspace) 
     else: 
      return "You don't have permission to view this space!" 
    except: 
     db.session.rollback() 
     return 'Something went wrong' 
    finally: 
     db.session.close() 
+1

数据库连接将不会被关闭,因为finally因为前面的'return'而没有运行。 –

+0

我认为这与Boto3有关。我已经编辑了我的问题。知道最后甚至没有被执行,这仍然是件好事。我将在每个try块的末尾添加db.session.close()。谢谢。 – user3080315

+0

@KlausD .:那是不正确的。无论“返回”,“finally”块都会运行。 [这里是文档。](https://docs.python.org/2/tutorial/errors.html#defining-clean-up-actions) –

回答

0

如果您在数据库会话中编写装饰器并执行您的方法,它将会非常干净。像这样

def db_session(): 
    def wrapper(func): 
     def wrapped(*args, **kwargs): 
      # Executing the handler inside a db context 
      with Session as session: 
       try: 
        return func(session, *args, **kwargs) 
       except: 
        session.rollback() 

@app.route('/space/<spacename>', methods=['GET', 'POST']) 
@login_required 
@db_session() 
def showspace(session, spacename): 
    # your code 
+1

'finally'套件不会执行。从文档:[“try语句的任何其他子句通过break,continue或return语句留下时,finally子句也会执行”。“](https://docs.python.org/ 2 /教程/ errors.html#限定-清理-动作)。 –

+0

谢谢。我正在使用Flask-SQLAlchemy。我认为你发布了香草SQLAlchemy。你能否将我转换成Flask-SQLAlchemy以确保我不会导致更多问题。 – user3080315

+0

@ZachGates,是的,我编辑了我的答案。谢谢 – Juggernaut