我为你创建了一个包含完整解决方案的 github :)
https://github.com/researcher2/stackoverflow_57120430 https://github.com/researcher2/stackoverflow_57120430
有几件事:
避免 SQL 注入
我建议在执行原始 sql 语句时使用绑定,我的代码反映了这一点。在偶然发现这一点之前,我花了很长时间试图让它与你的声明一起工作:
Python SQLite 在 LIKE 中使用通配符替换参数 https://stackoverflow.com/questions/3105249/python-sqlite-parameter-substitution-with-wildcards-in-like
基本上,您不能将绑定放入 LIKE '%?%' 内,因为引号会导致替换标记被忽略。
相反,你只需要做 LIKE ?并手动构建替换。
使用会话
所有会话信息都经过 JSON 序列化,然后发送到客户端。在这种情况下,行记录不是 JSON 可序列化的。这对我来说是一个错误:
TypeError: Object of type 'RowProxy' is not JSON serializable
我可能不会在这里使用会话,因为客户端不需要知道这一点,因为无论如何你都会为他们构建一个带有信息的漂亮 html 页面。只需使用 python 字典并将其传递给模板引擎即可。我的代码确实使用了会话,因为这就是您开始的地方。
万一 github 宕机了:
from flask import request, render_template, session
from app import app, db
@app.route("/", methods=['GET','POST'])
def index():
if request.method == "POST":
searchQuery = request.form.get("searchQuery")
print(searchQuery)
# Avoid SQL Injection Using Bindings
sql = "SELECT isbn, author, title \
FROM book \
WHERE isbn LIKE :x \
OR author LIKE :y \
OR title LIKE :z"
# I spent an hour wondering why I couldnt put the bindings inside the wildcard string...
# https://stackoverflow.com/questions/3105249/python-sqlite-parameter-substitution-with-wildcards-in-like
matchString = "%{}%".format(searchQuery)
stmt = db.text(sql).bindparams(x=matchString, y=matchString, z=matchString)
results = db.session.execute(stmt).fetchall()
print(results)
session["books"] = []
for row in results:
# A row is not JSON serializable so we pull out the pieces
book = dict()
book["isbn"] = row[0]
book["author"] = row[1]
book["title"] = row[2]
session["books"].append(book)
return render_template("index.html", searchedFor=searchQuery, books=session["books"])
return render_template("index.html")