我在更新SQL表时包含了值,但SQL仍然将我的值视为;没有;??(如果我正确获得错误消息)
我仍然是CS的初学者,我正在完成CS50的最后一个项目。我正在使用flask框架构建一个web应用程序。SQLite用于处理数据库 该web应用程序旨在让用户阅读不同瑜伽课程的信息(并预订,这是一项尚未添加的功能)。它还应该让管理员在以管理员身份登录后,轻松地(1)添加新的瑜伽课程,(2)在网站上更新现有课程的详细信息。我现在遇到的问题与(2)有关。当我试图用HTML表单中的输入更新表信息时,它总是显示错误消息 sqlalchemy.exc.CompileError:不知道如何呈现文字SQL值:无 我数据库中的一个表是“时间表”,每行代表一个班级。该表包含id(用作主键)、日期、价格等列 以管理员身份登录后,管理员可以在相关页面的HTML表单中输入信息,以便在时间表中添加新行,即添加新类。我已经测试过了,应该可以正常工作 但是,当尝试更新现有类的详细信息时,它总是显示错误500(内部服务器错误)。我目前的做法是:我在更新SQL表时包含了值,但SQL仍然将我的值视为;没有;??(如果我正确获得错误消息),sql,sqlite,flask,sqlalchemy,cs50,Sql,Sqlite,Flask,Sqlalchemy,Cs50,我仍然是CS的初学者,我正在完成CS50的最后一个项目。我正在使用flask框架构建一个web应用程序。SQLite用于处理数据库 该web应用程序旨在让用户阅读不同瑜伽课程的信息(并预订,这是一项尚未添加的功能)。它还应该让管理员在以管理员身份登录后,轻松地(1)添加新的瑜伽课程,(2)在网站上更新现有课程的详细信息。我现在遇到的问题与(2)有关。当我试图用HTML表单中的输入更新表信息时,它总是显示错误消息 sqlalchemy.exc.CompileError:不知道如何呈现文字SQL值:
- 我以2021-06-04的课程为例
action=“/admin/manageclass”
和method=“post”
,它将被转移到我的应用程序.py中的相关路径
manageclass()
处理“ID”(如上所述预先填写)和表单中添加的其他信息。我的部分代码如下所示-假设我只需要更改类的价格,我只显示与类价格相关的部分,以便您更容易阅读
@app.route("/admin/manageclass", methods=["GET", "POST"])
@login_required
def manageclass():
if request.method == "GET":
# Check whether the user is admin ...
# If yes, show the table for classes that can be managed ...
else:
# Handle class ID
class_id = request.form.get("class_id", type=int)
...
# Handle price (similar code for other items such as location)
price = request.form.get("price", type=int)
# When price is provided (similar code for other items such as location)
if price:
db.execute("UPDATE timetable SET price = ? WHERE id = ?", price, class_id)
...
# Return to the manageclass page after successful information update ...
db.execute("UPDATE timetable SET price = ? WHERE id = ?", price, class_id)
price
和class\u id
都不是零
ERROR: Exception on /admin/manageclass [POST]
Traceback (most recent call last):
File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 2447, in wsgi_app
response = self.full_dispatch_request()
File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1952, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1821, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python3.9/site-packages/flask/_compat.py", line 39, in reraise
raise value
File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1950, in full_dispatch_request
rv = self.dispatch_request()
File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1936, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/home/ubuntu/project/application.py", line 35, in decorated_function
return f(*args, **kwargs)
File "/home/ubuntu/project/application.py", line 338, in manageclass
db.execute("UPDATE timetable SET price = ? WHERE id = ?", price, class_id)
File "/usr/local/lib/python3.9/site-packages/cs50/sql.py", line 21, in decorator
return f(*args, **kwargs)
File "/usr/local/lib/python3.9/site-packages/cs50/sql.py", line 178, in execute
_args = ", ".join([str(self._escape(arg)) for arg in args])
File "/usr/local/lib/python3.9/site-packages/cs50/sql.py", line 178, in <listcomp>
_args = ", ".join([str(self._escape(arg)) for arg in args])
File "/usr/local/lib/python3.9/site-packages/cs50/sql.py", line 475, in _escape
return __escape(value)
File "/usr/local/lib/python3.9/site-packages/cs50/sql.py", line 465, in __escape
sqlalchemy.types.NullType().literal_processor(self._engine.dialect)(value))
File "/usr/local/lib/python3.9/site-packages/sqlalchemy/sql/sqltypes.py", line 3101, in process
raise exc.CompileError(
sqlalchemy.exc.CompileError: Don't know how to render literal SQL value: None
通过删除WHERE子句,对以下内容进行修改:
db.execute("UPDATE timetable SET price = ?", price)
如前所示,不再存在SQL编译错误。因此,我相信问题与WHERE条款有关。当然,没有任何地方是不可取的,因为所有类别的价格都会发生变化。但我希望这一小部分信息能够有助于进一步调查这一问题
——第二次更新---
我用我的代码做了一些其他的尝试,当我把一个整数(而不是变量class_id
)传递到WHERE子句时,没有错误:
db.execute("UPDATE timetable SET price = ? WHERE id = ?", price, 7)
因此,我认为问题在于变量class\u id,它实际上是request.form.get(“class\u id”,type=int)
。其他一些在线资源建议,request.form.get
返回一个NoneType
;它也许可以解释为什么错误消息显示我的值为None
但是,即使我在request.form.get
中添加了一个参数type=int
(就像我上面所做的那样),它仍然不起作用
我还尝试了request.values.get
,但仍然不起作用
我还尝试使用int()
将该值强制转换为整数,但效果并不理想
所以,这个问题仍然没有解决。但希望我更接近最终解决方案。感谢James Z编辑我的文章,使其更具可读性!我刚才还添加了删除WHERE子句的结果作为试验。如果
request.get('class_id')
返回None
,则从浏览器发布的表单数据中没有class_id
。检查表单HTML中input
标记的name
属性。@snakecharmerb是的,我害怕那个愚蠢的错误,所以我检查了HTML表单中的ID输入(在上图中禁用并预先填充了7),我已经包含了属性name=“class\u ID”
。因此,值“7”应该已经过账。谢谢d接下来的步骤是(1)添加print()
语句,在代码中显示class\u id
的值(在引用变量的每行后面打印)(2)在浏览器的“开发人员”中打开“网络”选项卡,检查表单发布时发送的内容。@snakecharmerb非常感谢-结果是,当输入被禁用时,类id的值无法发布。我希望禁用它可以避免id被意外更改(因此错误类的信息将被更改),但我不知道这只会使我的整个应用程序死亡。您不仅在帮助我处理这个问题,还向我暗示了一些调试的实际经验。非常感谢!
db.execute("UPDATE timetable SET price = ? WHERE id = ?", price, 7)