sqlalchemy.exc.DataError: (psycopg2.errors.InvalidTextRepresentation) invalid input syntax for type integer: "B1"
sqlalchemy.exc.DataError: (psycopg2.errors.InvalidTextRepresentation) invalid input syntax for type integer: "B1"
我正在尝试使用 ID 在我的 Flask 应用程序上登录管理员,当我注册时它完美地接受了输入,但是当从数据库 (postgresql) 获取值时它显示 "DataError" 我已将输入作为 HTML 形式的字母数字
这是我的代码:
在 model.py 我已经为数据库编写代码来创建列
model.py
class Admin(UserMixin, db.Model):
id = db.Column(db.String(1000), primary_key=True )
name = db.Column(db.String(1000))
email = db.Column(db.String(100), unique=True)
password = db.Column(db.String(100))
timestamp = db.Column(db.DateTime)
在此 auth.py 中,我为 POST 注册和登录方法编写了代码
auth.py
@auth.route('/admin')
def admin():
return render_template('admin.html')
@auth.route('/admin', methods=['POST'])
def admin_post():
id = request.form.get('id')
password = request.form.get('password')
remember = True if request.form.get('remember') else False
admins = Admin.query.filter_by(id=id).first()
# check if the user actually exists
# take the user-supplied password, hash it, and compare it to the hashed password in the database
if not admins or not check_password_hash(admins.password, password):
flash('Please check your login details and try again.')
# if the user doesn't exist or password is wrong, reload the page
return redirect(url_for('auth.admin'))
# if the above check passes, then we know the user has the right credentials
login_user(admins, remember=remember)
return redirect(url_for('main.adminOP'))
@auth.route('/admin-signup')
def adminsignup():
return render_template('admin-signup.html')
@auth.route('/admin-signup', methods=['POST'])
def adminsignup_post():
id = request.form.get('id')
email = request.form.get('email')
name = request.form.get('name')
password = request.form.get('password')
timestamp = datetime.now()
# if this returns a admin, then the email already exists in database
admins = Admin.query.filter_by(email=email).first()
if admins: # if a user is found, we want to redirect back to signup page so user can try again
flash('Email address already exists')
return redirect(url_for('auth.adminsignup'))
# create a new user with the form data. Hash the password so the plaintext version isn't saved.
new_admin = Admin(id=id, email=email, name=name,
password=generate_password_hash(password, method='sha256'), timestamp=timestamp)
# add the new user to the database
db.session.add(new_admin)
db.session.commit()
return redirect(url_for('auth.admin'))
回溯捕获到的错误是:
sqlalchemy.exc.DataError: (psycopg2.errors.InvalidTextRepresentation) invalid input syntax for type
integer: "B1"
LINE 3: WHERE person.id = 'B1'
^
[SQL: SELECT person.id AS person_id, person.email AS person_email, person.password AS person_password,
person.name AS person_name, person.timestamp AS person_timestamp
FROM person
WHERE person.id = %(pk_1)s]
[parameters: {'pk_1': 'B1'}]
(Background on this error at: http://sqlalche.me/e/14/9h9h)
这里B1是id
admin-signup.html
正如我之前所说,我在输入字段中使用了字母数字
{% extends "base.html" %}
{% block content %}
<div class="column is-4 is-offset-4">
<h3 class="title has-text-info">Sign Up</h3>
<div class="box">
{% with messages = get_flashed_messages() %}
{% if messages %}
<div class="notification is-danger">
{{ messages[0] }}. Go to <a href="{{ url_for('auth.admin') }}">login page</a>.
</div>
{% endif %}
{% endwith %}
<form method="POST" action="/admin-signup">
<div class="field">
<div class="control has-icons-left has-icons-right">
<input class="input is-large" type="text" name="id" placeholder="Your ID" autofocus="" pattern="[a-zA-Z0-9]+"><span
class="icon is-small is-left">
</span>
<small> Remember: ID is you employee number </small>
</div>
</div>
<div class="field">
<div class="control has-icons-left has-icons-right">
<input class="input is-large" type="email" aria-required="true" name="email" placeholder="Email"
autofocus=""><span class="icon is-small is-left">
</span>
</div>
</div>
<div class="field">
<div class="control has-icons-left has-icons-right">
<input class="input is-large" type="text" aria-required="true" name="name" placeholder="Name"
autofocus=""><span class="icon is-small is-left">
</span>
</div>
</div>
<div class="field">
<div class="control has-icons-left has-icons-right">
<input class="input is-large" type="password" aria-required="true" name="password"
placeholder="Password"><span class="icon is-small is-left">
</span>
</div>
</div>
<button class="button is-block is-info is-large is-fullwidth">Sign Up</button>
</form>
</div>
</div>
{% endblock %}
admin.html
{% extends "base.html" %}
{% block content %}
<div class="column is-4 is-offset-4">
<h3 class="title has-text-info">Admin Login</h3>
<div class="box">
{% with messages = get_flashed_messages() %}
{% if messages %}
<div class="notification is-danger">
{{ messages[0] }}
</div>
{% endif %}
{% endwith %}
<form method="POST" action="/admin">
<div class="field">
<div class="control has-icons-left has-icons-right">
<input class="input is-large" type="text" name="id" placeholder="Your ID" autofocus="" required pattern="[a-zA-Z0-9]+"><span
class="icon is-small is-left">
</span>
<small> HINT: ID is you employee number </small>
</div>
</div>
<div class="field">
<div class="control has-icons-left has-icons-right">
<input class="input is-large" type="password" name="password" placeholder="Your Password"><span
class="icon is-small is-left">
</span>
</div>
</div>
<div class="field">
<label class="checkbox">
<input type="checkbox">
Remember me
</label>
</div>
<button class="button is-block is-info is-large is-fullwidth">Login</button>
</form>
</div>
</div>
{% endblock %}
编辑代码后,我在调试时遇到了同样的错误
这是人物模型
class person(UserMixin, db.Model):
# primary keys are required by SQLAlchemy
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(100), unique=True)
password = db.Column(db.String(100))
name = db.Column(db.String(1000))
timestamp = db.Column(db.DateTime)
问题是您的 person
模型中的列 id
是整数,而不是字符串。您的 load_user
函数查询 person
模型提供的键 B1
,无法转换为整数。
如果您打算查询您的 Admin
模型并且 还 根据登录者查询您的 person
模型,您应该在您的登录期间的用户会话,并在 load_user
函数中检索它。查看 了解更多详情。
但是如果你需要区别对待你的用户(User#1 是管理员,而 User#2 不是),你真的应该考虑在你的模型中使用布尔标志,像这样:
class User(UserMixin, db.Model):
id = db.Column(db.String(1000), primary_key=True )
name = db.Column(db.String(1000))
# ...
is_admin = db.Column(db.Boolean)
你真的应该避免让两个用户的模型使用不同类型的密钥,随着时间的推移它会变得非常混乱。
如果您的 Flask 应用程序倾向于增长并拥有多种类型的用户,您应该考虑采用 'user roles' 的概念。查看 Flask-Principal 为此。
旧答案
问题可能是因为您的模型和数据库不同步。在某些时候,您可能有 id = db.Column(db.Integer, primary_key=True)
然后 运行 db.create_all()
的开发过程,然后将 id 更改为 id = db.Column(db.String(1000), primary_key=True)
.
简单来说,Flask认为id是string,而PostgreSQL确定是int。可以肯定的是,您可以使用以下方法检查 table person
的 DDL:
pg_dump -U your_user your_database -t person --schema-only
请注意 flask/flask-sqlalchemy 不会自动迁移,更改模型后您应该重新创建数据库或手动应用更改(选择由您决定)。
我正在尝试使用 ID 在我的 Flask 应用程序上登录管理员,当我注册时它完美地接受了输入,但是当从数据库 (postgresql) 获取值时它显示 "DataError" 我已将输入作为 HTML 形式的字母数字
这是我的代码:
在 model.py 我已经为数据库编写代码来创建列
model.py
class Admin(UserMixin, db.Model):
id = db.Column(db.String(1000), primary_key=True )
name = db.Column(db.String(1000))
email = db.Column(db.String(100), unique=True)
password = db.Column(db.String(100))
timestamp = db.Column(db.DateTime)
在此 auth.py 中,我为 POST 注册和登录方法编写了代码
auth.py
@auth.route('/admin')
def admin():
return render_template('admin.html')
@auth.route('/admin', methods=['POST'])
def admin_post():
id = request.form.get('id')
password = request.form.get('password')
remember = True if request.form.get('remember') else False
admins = Admin.query.filter_by(id=id).first()
# check if the user actually exists
# take the user-supplied password, hash it, and compare it to the hashed password in the database
if not admins or not check_password_hash(admins.password, password):
flash('Please check your login details and try again.')
# if the user doesn't exist or password is wrong, reload the page
return redirect(url_for('auth.admin'))
# if the above check passes, then we know the user has the right credentials
login_user(admins, remember=remember)
return redirect(url_for('main.adminOP'))
@auth.route('/admin-signup')
def adminsignup():
return render_template('admin-signup.html')
@auth.route('/admin-signup', methods=['POST'])
def adminsignup_post():
id = request.form.get('id')
email = request.form.get('email')
name = request.form.get('name')
password = request.form.get('password')
timestamp = datetime.now()
# if this returns a admin, then the email already exists in database
admins = Admin.query.filter_by(email=email).first()
if admins: # if a user is found, we want to redirect back to signup page so user can try again
flash('Email address already exists')
return redirect(url_for('auth.adminsignup'))
# create a new user with the form data. Hash the password so the plaintext version isn't saved.
new_admin = Admin(id=id, email=email, name=name,
password=generate_password_hash(password, method='sha256'), timestamp=timestamp)
# add the new user to the database
db.session.add(new_admin)
db.session.commit()
return redirect(url_for('auth.admin'))
回溯捕获到的错误是:
sqlalchemy.exc.DataError: (psycopg2.errors.InvalidTextRepresentation) invalid input syntax for type
integer: "B1"
LINE 3: WHERE person.id = 'B1'
^
[SQL: SELECT person.id AS person_id, person.email AS person_email, person.password AS person_password,
person.name AS person_name, person.timestamp AS person_timestamp
FROM person
WHERE person.id = %(pk_1)s]
[parameters: {'pk_1': 'B1'}]
(Background on this error at: http://sqlalche.me/e/14/9h9h)
这里B1是id
admin-signup.html
正如我之前所说,我在输入字段中使用了字母数字
{% extends "base.html" %}
{% block content %}
<div class="column is-4 is-offset-4">
<h3 class="title has-text-info">Sign Up</h3>
<div class="box">
{% with messages = get_flashed_messages() %}
{% if messages %}
<div class="notification is-danger">
{{ messages[0] }}. Go to <a href="{{ url_for('auth.admin') }}">login page</a>.
</div>
{% endif %}
{% endwith %}
<form method="POST" action="/admin-signup">
<div class="field">
<div class="control has-icons-left has-icons-right">
<input class="input is-large" type="text" name="id" placeholder="Your ID" autofocus="" pattern="[a-zA-Z0-9]+"><span
class="icon is-small is-left">
</span>
<small> Remember: ID is you employee number </small>
</div>
</div>
<div class="field">
<div class="control has-icons-left has-icons-right">
<input class="input is-large" type="email" aria-required="true" name="email" placeholder="Email"
autofocus=""><span class="icon is-small is-left">
</span>
</div>
</div>
<div class="field">
<div class="control has-icons-left has-icons-right">
<input class="input is-large" type="text" aria-required="true" name="name" placeholder="Name"
autofocus=""><span class="icon is-small is-left">
</span>
</div>
</div>
<div class="field">
<div class="control has-icons-left has-icons-right">
<input class="input is-large" type="password" aria-required="true" name="password"
placeholder="Password"><span class="icon is-small is-left">
</span>
</div>
</div>
<button class="button is-block is-info is-large is-fullwidth">Sign Up</button>
</form>
</div>
</div>
{% endblock %}
admin.html
{% extends "base.html" %}
{% block content %}
<div class="column is-4 is-offset-4">
<h3 class="title has-text-info">Admin Login</h3>
<div class="box">
{% with messages = get_flashed_messages() %}
{% if messages %}
<div class="notification is-danger">
{{ messages[0] }}
</div>
{% endif %}
{% endwith %}
<form method="POST" action="/admin">
<div class="field">
<div class="control has-icons-left has-icons-right">
<input class="input is-large" type="text" name="id" placeholder="Your ID" autofocus="" required pattern="[a-zA-Z0-9]+"><span
class="icon is-small is-left">
</span>
<small> HINT: ID is you employee number </small>
</div>
</div>
<div class="field">
<div class="control has-icons-left has-icons-right">
<input class="input is-large" type="password" name="password" placeholder="Your Password"><span
class="icon is-small is-left">
</span>
</div>
</div>
<div class="field">
<label class="checkbox">
<input type="checkbox">
Remember me
</label>
</div>
<button class="button is-block is-info is-large is-fullwidth">Login</button>
</form>
</div>
</div>
{% endblock %}
编辑代码后,我在调试时遇到了同样的错误
这是人物模型
class person(UserMixin, db.Model):
# primary keys are required by SQLAlchemy
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(100), unique=True)
password = db.Column(db.String(100))
name = db.Column(db.String(1000))
timestamp = db.Column(db.DateTime)
问题是您的 person
模型中的列 id
是整数,而不是字符串。您的 load_user
函数查询 person
模型提供的键 B1
,无法转换为整数。
如果您打算查询您的 Admin
模型并且 还 根据登录者查询您的 person
模型,您应该在您的登录期间的用户会话,并在 load_user
函数中检索它。查看
但是如果你需要区别对待你的用户(User#1 是管理员,而 User#2 不是),你真的应该考虑在你的模型中使用布尔标志,像这样:
class User(UserMixin, db.Model):
id = db.Column(db.String(1000), primary_key=True )
name = db.Column(db.String(1000))
# ...
is_admin = db.Column(db.Boolean)
你真的应该避免让两个用户的模型使用不同类型的密钥,随着时间的推移它会变得非常混乱。
如果您的 Flask 应用程序倾向于增长并拥有多种类型的用户,您应该考虑采用 'user roles' 的概念。查看 Flask-Principal 为此。
旧答案
问题可能是因为您的模型和数据库不同步。在某些时候,您可能有 id = db.Column(db.Integer, primary_key=True)
然后 运行 db.create_all()
的开发过程,然后将 id 更改为 id = db.Column(db.String(1000), primary_key=True)
.
简单来说,Flask认为id是string,而PostgreSQL确定是int。可以肯定的是,您可以使用以下方法检查 table person
的 DDL:
pg_dump -U your_user your_database -t person --schema-only
请注意 flask/flask-sqlalchemy 不会自动迁移,更改模型后您应该重新创建数据库或手动应用更改(选择由您决定)。