Обновить случайную строку в БД с помощью 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. В этом запросе столбец да или нет обновляется немедленно.
Какие-нибудь мысли?
Спасибо
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
Я думаю, что вам нужно добавить обновление в сеанс перед фиксацией, используя код, подобный этому:
Это шаблон, который я использую для базового обновления в Flask-SQLAlchemy.[...] row.yes += 1 db.session.add(row) db.session.commit() [...]
Comments