Flask_SQLAlchemy 声称我的值不是布尔值?
Flask_SQLAlchemy is claiming my value is not boolean?
我运行进入如下错误:
File "/home/sandbox/.local/lib/python3.6/site-packages/sqlalchemy/sql/sqltypes.py", line 1973, in _strict_as_bool
raise TypeError("Not a boolean value: %r" % (value,))
sqlalchemy.exc.StatementError: (builtins.TypeError) Not a boolean value: 'True'
[SQL: INSERT INTO projects (status) VALUES (?)]
[parameters: [{'status': 'True'}]]
127.0.0.1 - - [12/May/2022 21:53:22] "POST / HTTP/1.1" 500 -
我在我的主要路线上尝试了从 0|1、FALSE|TRUE、False|True 开始的所有 运行 布尔值输入。我还尝试在引号之间放入布尔值。
我做错了什么?
import os
from flask import Flask
from flask import render_template
from flask import request
from flask import redirect
from flask_sqlalchemy import SQLAlchemy
database_file = "sqlite:///DATA/DATA.db"
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = database_file
db = SQLAlchemy(app)
class Projects(db.Model):
__tablename__="projects"
status = db.Column(db.Boolean, default=False, nullable=False, primary_key=True)
def __repr__(self):
return f"projects('{self.status}')"
db.create_all()
@app.route("/", methods=["GET", "POST"])
def home():
if request.form:
status = Projects(status=request.form.get("status"))
db.session.add(status)
db.session.commit()
return render_template("home.html")
我的基本路线如下
{% extends "layout.html" %}
{% block body %}
<h1> Add new project </h1>
<form method="POST" action="/">
<select name="status" placeholder="Project Status">
<option value=False> Not Active </option>
<option value=True> Active </option>
</select>
<input type="submit" value="Register Data">
</form>
{% endblock %}
您遇到的问题是表单提交将选择值作为字符串返回 - 字面上 "True"
或 "False"
- 而 SQL 驱动程序需要布尔类型。
有一个Python标准库函数distutils.util.strtobool which can safely convert a representation of a true or false value into a boolean type, raising a ValueError if someone puts something naughty into your API (this is much preferred to using eval()
which shouldn't be used on untrusted input).
我会将您的路线更新为如下内容:
# At the top
from distutils.util import strtobool
@app.route("/", methods=["GET", "POST"])
def home():
if request.form:
try:
form_status = strtobool(request.form.get("status").lower())
status = Projects(status=form_status)
db.session.add(status)
db.session.commit()
except ValueError:
# Handle the error - e.g. flash a message to the user
flash("Invalid input")
return render_template("home.html")
strtobool
需要注意的一件事是 distutils
现在已从 Python 3.10 开始弃用,并将在 3.12 中删除。 显示了它作为一个函数的实现,这是非常简单的,因此对于任何预计会持续到 Python 3.12.
之后的代码,都值得将其包含在您自己的实用程序函数中
我运行进入如下错误:
File "/home/sandbox/.local/lib/python3.6/site-packages/sqlalchemy/sql/sqltypes.py", line 1973, in _strict_as_bool
raise TypeError("Not a boolean value: %r" % (value,))
sqlalchemy.exc.StatementError: (builtins.TypeError) Not a boolean value: 'True'
[SQL: INSERT INTO projects (status) VALUES (?)]
[parameters: [{'status': 'True'}]]
127.0.0.1 - - [12/May/2022 21:53:22] "POST / HTTP/1.1" 500 -
我在我的主要路线上尝试了从 0|1、FALSE|TRUE、False|True 开始的所有 运行 布尔值输入。我还尝试在引号之间放入布尔值。 我做错了什么?
import os
from flask import Flask
from flask import render_template
from flask import request
from flask import redirect
from flask_sqlalchemy import SQLAlchemy
database_file = "sqlite:///DATA/DATA.db"
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = database_file
db = SQLAlchemy(app)
class Projects(db.Model):
__tablename__="projects"
status = db.Column(db.Boolean, default=False, nullable=False, primary_key=True)
def __repr__(self):
return f"projects('{self.status}')"
db.create_all()
@app.route("/", methods=["GET", "POST"])
def home():
if request.form:
status = Projects(status=request.form.get("status"))
db.session.add(status)
db.session.commit()
return render_template("home.html")
我的基本路线如下
{% extends "layout.html" %}
{% block body %}
<h1> Add new project </h1>
<form method="POST" action="/">
<select name="status" placeholder="Project Status">
<option value=False> Not Active </option>
<option value=True> Active </option>
</select>
<input type="submit" value="Register Data">
</form>
{% endblock %}
您遇到的问题是表单提交将选择值作为字符串返回 - 字面上 "True"
或 "False"
- 而 SQL 驱动程序需要布尔类型。
有一个Python标准库函数distutils.util.strtobool which can safely convert a representation of a true or false value into a boolean type, raising a ValueError if someone puts something naughty into your API (this is much preferred to using eval()
which shouldn't be used on untrusted input).
我会将您的路线更新为如下内容:
# At the top
from distutils.util import strtobool
@app.route("/", methods=["GET", "POST"])
def home():
if request.form:
try:
form_status = strtobool(request.form.get("status").lower())
status = Projects(status=form_status)
db.session.add(status)
db.session.commit()
except ValueError:
# Handle the error - e.g. flash a message to the user
flash("Invalid input")
return render_template("home.html")
strtobool
需要注意的一件事是 distutils
现在已从 Python 3.10 开始弃用,并将在 3.12 中删除。