python bottle+sqlite3で複数ユーザの更新を受け付ける方法
python bottleでsqlite3にアクセスして回答を保持する簡単なクイズアプリを作成しています。
下記のサンプルコードを1人で実行すると問題なく動作するのですが、複数人で実行すると一斉に回答した時に内部でsqlite3.OperationalError
が発生し、回答者には500 Internal Server Error
のエラー画面が表示されてしまいます。
sqlite3を数十人で一斉に書き込んでもロックしないようにするにはどのように設定するべきでしょうか。
Python 3.6.0
bottle 0.12.13
Windows 10 64bit / Windows Server 2012
question.py
#coding:utf-8
from bottle import run,route,template,redirect,request,get,post,static_file
from datetime import datetime
import sqlite3
import os
@route("/")
def index():
if not os.path.exists(db_name):
init_table(db_name)
question = [u'パンはパンでも', u'食べられないパンは', u'なーんだ?']
answers = [[1, u'くさったパン'], [2, u'パンデミック'], [3, u'フライパン(英: a fried bread)']]
return template("index",id=id,question=question,answers=answers)
@route("/answer",method=["POST"])
def answer():
name = request.forms.user_name
ans = request.forms.answer
with sqlite3.connect(db_name) as conn:
sql = "replace into answer values(?, ?)"
conn.execute(sql, (name, ans))
conn.commit()
return redirect("/")
def init_table(db_name):
with sqlite3.connect(db_name) as conn:
conn.execute('create table answer (name varchar(50) primary key, ans integer)')
db_name = 'myquiz.db'
run(host="localhost",port=8000,reloader=True)
#run(host="192.168.X.X",port=8000,reloader=True)
index.html
<!DOCTYPE html>
<html lang="jp">
<head>
<meta charset="UTF-8">
<title>クイズアプリ</title>
</head>
<body>
<div>
% for line in question:
{{line}}<br/>
% end
</div>
<form method="POST" action="/answer">
<table border="0">
<tr>
<td align="right"><b> 名前:</b></td>
<td><input type="text" name="user_name" size="30" maxlength="20"></td>
</tr>
</table>
<fieldset>
<legend>Answer</legend>
% for answer in answers:
<label><input type="radio" name="answer" value="{{answer[0]}}"/>{{answer[1]}}</label><br/>
% end
</fieldset>
<input class="sbutton" type="submit" value="回答する(SUBMIT)"/>
</form>
</body>
</html>
コンソールに表示される内部エラー
Traceback (most recent call last):
File "C:\Users\payaneco\AppData\Local\Programs\Python\Python36-32\lib\site-packages\bottle.py", line 862, in _handle
return route.call(**args)
File "C:\Users\payaneco\AppData\Local\Programs\Python\Python36-32\lib\site-packages\bottle.py", line 1740, in wrapper
rv = callback(*a, **ka)
File ".\question.py", line 21, in answer
conn.execute(sql, (name, ans))
sqlite3.OperationalError: database is locked
回答者に表示されるエラー
Error: 500 Internal Server Error
Sorry, the requested URL 'http://localhost:8000/answer' caused an error:
Internal Server Error