使用Flask-SqlAlchemy编辑Sqlite条目时遭遇ProgrammingError错误
编辑SQLite数据库条目提交时出现以下错误:
sqlalchemy.exc.ProgrammingError: (sqlite3.ProgrammingError) Error binding parameter 1: type 'StringField' is not supported
[SQL: UPDATE blog_post SET title=?, subtitle=?, body=?, author=?, img_url=? WHERE blog_post.id = ?]
[parameters: (<wtforms.fields.simple.StringField object at 0x0000020F99680610>, <wtforms.fields.simple.StringField object at 0x0000020F99680C10>, <flask_ckeditor.fields.CKEditorField object at 0x0000020F99682250>, <wtforms.fields.simple.StringField object at 0x0000020F99682ED0>, <wtforms.fields.simple.StringField object at 0x0000020F99682310>, 2)]
数据库表定义:
class BlogPost(db.Model): id = db.Column(db.Integer, primary_key=True) title = db.Column(db.String(250), unique=True, nullable=False) subtitle = db.Column(db.String(250), nullable=False) date = db.Column(db.String(250), nullable=False) body = db.Column(db.Text, nullable=False) author = db.Column(db.String(250), nullable=False) img_url = db.Column(db.String(250), nullable=False)
条目编辑代码:
@app.route("/edit/<int:post_id>", methods=["GET", "POST"]) def edit_post(post_id): with app.app_context(): post = db.session.query(BlogPost).filter_by(id = post_id).first() print(post.__dict__) # post_data = CreatePostForm(obj=post) post_data = CreatePostForm( title = post.title, subtitle = post.subtitle, author = post.author, img_url = post.img_url, body = post.body ) if post_data.validate_on_submit(): print(post.title) post.title = post_data.title post.subtitle = post_data.subtitle post.author = post_data.author post.img_url = post_data.img_url post.body = post_data.body db.session.commit() return redirect(url_for('show_post', index = post_id)) return render_template('make-post.html', form = post_data, is_edit = True)
错误根源是你直接将WTForms的字段对象(如post_data.title)赋值给了数据库模型字段,而非字段对应的实际输入值。WTForms字段必须通过.data属性才能获取用户提交的内容。
修改提交逻辑部分的代码,为每个字段添加.data:
if post_data.validate_on_submit(): print(post.title) post.title = post_data.title.data post.subtitle = post_data.subtitle.data post.author = post_data.author.data post.img_url = post_data.img_url.data post.body = post_data.body.data db.session.commit() return redirect(url_for('show_post', index = post_id))
另外,初始化表单时推荐使用obj=post自动填充字段,比手动赋值更简洁不易出错:
# 替换原手动初始化代码 post_data = CreatePostForm(obj=post)
内容的提问来源于stack exchange,提问作者Daikyu

