2016-11-24 4 views
2

Flask와 Flask-Sqlalchemy를 사용하여 Sqlite 데이터베이스에서 무작위로 선택된 행을 업데이트하려고했습니다. "word", "yes"및 "no"라는 열이있는 데이터베이스의 행이 몇 개 있습니다. 여기서 word는 문자열이고 yes 및 no는 정수입니다. "투표"보기에는 두 가지 버튼이 있습니다 (예 및 아니오). 버튼을 누르면 해당 코드가 실행되고 예 또는 아니요 열이 증가해야하며보기가 Word 표의 새로운 임의의 단어로 업데이트됩니다.Flask-Sqlalchemy를 사용하여 DB에서 임의의 행을 업데이트하십시오.

@app.route("/vote", methods=["GET", "POST"]) 
def vote(): 
    #Get random row from database 
    query = db.session.query(Word) 
    rowCount = int(query.count()) 
    row = query.offset(int(rowCount*random.random())).first() 

    #POST 

    # If "yes" button is pressed, increment yes column in database 
    if request.method == "POST": 
     if request.form.get("yes"): 
      row.yes += 1 
      db.session.commit() 
      return render_template("vote.html", row=row) 
    # otherwise increment no column 
     elif request.form.get("no"): 
      row.no += 1 
      db.session.commit() 
      return redirect(url_for("vote")) 

    #GET 

    # on get request, render vote.html 
    return render_template("vote.html", row=row) 

이 코드는 작동하지만 예 및 아니요 열은 다음 번에 임의의 단어로 돌아갈 때만 업데이트됩니다. 단추를 클릭 한 직후에 브라우저를 닫으면 데이터베이스가 증가하지 않습니다. db.session.commit()과 관련이 있거나 세션에 관한 내용이 있다고 생각합니다.

row.yes += 1 

이 세션 객체에 저장하지만, 해당 데이터베이스 행이 다음 번에 조회 할 때 최선을 다하고 있습니다 : 것 같다. 이 쿼리와 함께 4의 id를 가진 행을 반환

row = Word.query.get(4) 

에서, 예 또는 아니오 열이 즉시 업데이트 : 내가 가진 방법의 상단에있는 쿼리를 교체 할 때이 코드는 작업을했다.

의견이 있으십니까?

감사

+0

귀하의 증분은 경쟁 조건에 취약합니다. 데이터베이스에서 증가분을 처리하도록해야합니다. 'row.yes = Word.yes + 1' – dirn

답변

2

감사합니다. 나는 그 문제를 알아 냈다. 데이터베이스가 실제로 제대로 작동했지만, 정확한 행을 증가시키지 않았습니다. 문제는 vote() 메서드를 호출 할 때마다 데이터베이스에서 임의의 행을 생성했기 때문에 GET 요청에 임의의 값이 있고 POST 요청에 다른 임의의 값이 있다는 것을 의미합니다. POST 요청에서 다른 임의 값.

로직을 "/ vote"라우트 getWord() 및 vote()에 대한 두 개의 메소드로 분리하고 행 생성을 위해 randRow() 메소드를 작성했습니다. getWord()가 호출 될 때 생성되는 무작위 행을 저장해야하므로 session 변수를 사용하여 vote() 메소드에서 임의의 행에 액세스 할 수있었습니다. 그것은 약간 장황하지만 작동하는 것 같습니다.

누구나이를 달성하는 방법에 대해 더 잘 알고 있습니까?

@app.route('/vote', methods=["GET"]) 
def getWord(): 
    wordObj = randRow() 
    session['word'] = wordObj.word 
    session['yesVotes'] = wordObj.yes 
    session['noVotes'] = wordObj.no 
    return render_template("vote.html", word=session['word'], yesVotes=session['yesVotes'], noVotes=session['noVotes']) 

@app.route('/vote', methods=["POST"]) 
def vote(): 
    # store session 'word' in word variable 
    # look up word in database and store object in wordObj 
    word = session['word'] 
    wordObj = Word.query.filter_by(word=word).first() 
    # check button press on vote view, increment yes or no column 
    # depending on which button was pressed 
    if request.form.get("yes"): 
     wordObj.yes = wordObj.yes + 1 
    elif request.form.get("no"): 
     wordObj.no = wordObj.no + 1 
    db.session.commit() 
    return redirect(url_for("getWord")) 

###### HELPERS ###### 

# returns a random row from the database 
def randRow(): 
    rowId = Word.query.order_by(func.random()).first().id 
    row = Word.query.get(rowId) 
    return row 
0

나는 당신이 전에 세션에 업데이트를 추가 할 필요가 생각하는 다음과 같은 코드를 사용하여 커밋 :

[...] 
    row.yes += 1 
    db.session.add(row) 
    db.session.commit() 
[...] 

내가 플라스크-SQLAlchemy의에서 기본 업데이트 사용 패턴의 그 .

+0

세션을 통해로드 된 경우 세션에 추가 할 필요가 없습니다. 'Model.query'는 그것을합니다. – dirn