Обновить случайную строку в БД с помощью Flask-Sqlalchemy



Я пытался обновить случайно выбранную строку в моей базе данных Sqlite с помощью Flask и Flask-Sqlalchemy. У меня есть всего несколько строк в базе данных со столбцами "word", "yes" и "no", где word-это строка, а yes и no-целые числа. На панели "голосовать" есть две кнопки: да и нет. Когда кнопка нажата, соответствующий код выполняется, должен увеличить столбец да или нет, и представление обновляется новым случайным словом из таблицы слов.



@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)


Это код работает, но столбцы да и нет обновляются только тогда, когда представление возвращается к случайному слову в следующий раз. Если я закрываю браузер сразу после нажатия кнопки, база данных не увеличивается. Я думаю, это как-то связано с БД.сессия.commit (), или что-то о сессии. Это выглядит так:



row.yes += 1


Сохраняется в объекте сеанса, но фиксируется только при следующем запросе этой строки базы данных. Этот код действительно работал, когда я заменил запрос в верхней части метод с:



row = Word.query.get(4)


, который возвращает строку с идентификатором 4. В этом запросе столбец да или нет обновляется немедленно.



Какие-нибудь мысли?



Спасибо

622   2  

2 ответов:

Спасибо всем. Я понял, в чем проблема. Увеличение базы данных на самом деле работало нормально, но я не увеличивал правильные строки. Проблема заключалась в том, что я генерировал случайную строку из базы данных при каждом вызове метода vote (), что означало, что я получал случайное значение для запроса GET и различное случайное значение для запроса POST, и в конечном итоге увеличивал это различное случайное значение в запросе POST.

Я разделил логику на два метода для " / голосования" route, getWord() и vote (), а также создали метод randRow () для генерации строк. Мне нужно было сохранить случайную строку, которая генерируется при вызове getWord (), поэтому я использовал переменные сеанса, чтобы получить доступ к случайной строке из метода 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

Я думаю, что вам нужно добавить обновление в сеанс перед фиксацией, используя код, подобный этому:

[...]
    row.yes += 1
    db.session.add(row)
    db.session.commit()
[...]
Это шаблон, который я использую для базового обновления в Flask-SQLAlchemy.

Comments

    Ничего не найдено.