Flask SQLAlchely UPDATE instead of INSERT



我正在学习Corey Schafer关于制作Flask Web应用程序的系列教程,但我做错了什么。因此,当涉及到从用户到数据库的新帖子时,它会将表单中的数据写入数据库,但当我试图从同一用户添加另一个帖子时,我会得到错误:

[SQL: UPDATE post SET user_id=? WHERE post.id = ?]
[parameters: (None, 1)]

我的models.py中有这个,不应该让user_id是None:

@login_manager.user_loader
def load_user(user_id):
return User.query.get(int(user_id))

登录路径:

@app.route('/login', methods=['GET', 'POST'])
def login():
if current_user.is_authenticated:
return redirect(url_for('home'))
form = LoginForm()
if form.validate_on_submit():
user = User.query.filter_by(username=form.username.data).first()
if user and bcrypt.check_password_hash(user.password, form.password.data):
login_user(user, remember=form.remember.data)
flash(f'Success.', category='success')
next_page = request.args.get('next')
return redirect(next_page) if next_page else redirect(url_for('home'))
else:
flash('Unsuccessful!', category='danger')
return render_template('login.html', title='Log In', form=form)

这是添加新帖子的路线:

@app.route('/post/new', methods=['GET', 'POST'])
@login_required
def new_product():
form = PostForm()
if form.validate_on_submit():
post = Post(name=form.name.data, content=form.content.data, author=current_user)
db.session.add(post)
db.session.commit()
flash('Created!', category='success')
return redirect(url_for('home'))
return render_template('new.html', title='Add Post', form=form, legend='New Post')

这就是形式:

class PostForm(FlaskForm):
name = StringField('Name', validators=[DataRequired()])
content = StringField('Content', validators=[DataRequired()])

在视频中,他发布了一个新帖子,但来自另一个用户帐户。我怎么能逃脱呢?

整个错误是这样的:

127.0.0.1 - - [26/Apr/2021 15:00:34] "POST /post/new HTTP/1.1" 500 -
Traceback (most recent call last):
File "D:PythonHTMLvenvLibsite-packagessqlalchemyenginebase.py", line 1705, in _execute_context
self.dialect.do_execute(
File "D:PythonHTMLvenvLibsite-packagessqlalchemyenginedefault.py", line 716, in do_execute
cursor.execute(statement, parameters)
sqlite3.IntegrityError: NOT NULL constraint failed: post.user_id
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "D:PythonHTMLvenvLibsite-packagesflaskapp.py", line 2464, in __call__
return self.wsgi_app(environ, start_response)
File "D:PythonHTMLvenvLibsite-packagesflaskapp.py", line 2450, in wsgi_app
response = self.handle_exception(e)
File "D:PythonHTMLvenvLibsite-packagesflaskapp.py", line 1867, in handle_exception
reraise(exc_type, exc_value, tb)
File "D:PythonHTMLvenvLibsite-packagesflask_compat.py", line 39, in reraise
raise value
File "D:PythonHTMLvenvLibsite-packagesflaskapp.py", line 2447, in wsgi_app
response = self.full_dispatch_request()
File "D:PythonHTMLvenvLibsite-packagesflaskapp.py", line 1952, in full_dispatch_request
rv = self.handle_user_exception(e)
File "D:PythonHTMLvenvLibsite-packagesflaskapp.py", line 1821, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "D:PythonHTMLvenvLibsite-packagesflask_compat.py", line 39, in reraise
raise value
File "D:PythonHTMLvenvLibsite-packagesflaskapp.py", line 1950, in full_dispatch_request
rv = self.dispatch_request()
File "D:PythonHTMLvenvLibsite-packagesflaskapp.py", line 1936, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "D:PythonHTMLblogLibsite-packagesflask_loginutils.py", line 272, in decorated_view
return func(*args, **kwargs)
File "D:PythonHTMLstoreroutes.py", line 101, in new_product
db.session.commit()
File "<string>", line 2, in commit
File "D:PythonHTMLvenvLibsite-packagessqlalchemyormsession.py", line 1423, in commit
self._transaction.commit(_to_root=self.future)
File "D:PythonHTMLvenvLibsite-packagessqlalchemyormsession.py", line 829, in commit
self._prepare_impl()
File "D:PythonHTMLvenvLibsite-packagessqlalchemyormsession.py", line 808, in _prepare_impl
self.session.flush()
File "D:PythonHTMLvenvLibsite-packagessqlalchemyormsession.py", line 3255, in flush
self._flush(objects)
File "D:PythonHTMLvenvLibsite-packagessqlalchemyormsession.py", line 3395, in _flush
transaction.rollback(_capture_exception=True)
File "D:PythonHTMLvenvLibsite-packagessqlalchemyutillanghelpers.py", line 70, in __exit__
compat.raise_(
File "D:PythonHTMLvenvLibsite-packagessqlalchemyutilcompat.py", line 211, in raise_
raise exception
File "D:PythonHTMLvenvLibsite-packagessqlalchemyormsession.py", line 3355, in _flush
flush_context.execute()
File "D:PythonHTMLvenvLibsite-packagessqlalchemyormunitofwork.py", line 453, in execute
rec.execute(self)
File "D:PythonHTMLvenvLibsite-packagessqlalchemyormunitofwork.py", line 627, in execute
util.preloaded.orm_persistence.save_obj(
File "D:PythonHTMLvenvLibsite-packagessqlalchemyormpersistence.py", line 234, in save_obj
_emit_update_statements(
File "D:PythonHTMLvenvLibsite-packagessqlalchemyormpersistence.py", line 998, in _emit_update_statements
c = connection._execute_20(
File "D:PythonHTMLvenvLibsite-packagessqlalchemyenginebase.py", line 1520, in _execute_20
return meth(self, args_10style, kwargs_10style, execution_options)
File "D:PythonHTMLvenvLibsite-packagessqlalchemysqlelements.py", line 313, in _execute_on_connection
return connection._execute_clauseelement(
File "D:PythonHTMLvenvLibsite-packagessqlalchemyenginebase.py", line 1389, in _execute_clauseelement
ret = self._execute_context(
File "D:PythonHTMLvenvLibsite-packagessqlalchemyenginebase.py", line 1748, in _execute_context
self._handle_dbapi_exception(
File "D:PythonHTMLvenvLibsite-packagessqlalchemyenginebase.py", line 1929, in _handle_dbapi_exception
util.raise_(
File "D:PythonHTMLvenvLibsite-packagessqlalchemyutilcompat.py", line 211, in raise_
raise exception
File "D:PythonHTMLvenvLibsite-packagessqlalchemyenginebase.py", line 1705, in _execute_context
self.dialect.do_execute(
File "D:PythonHTMLvenvLibsite-packagessqlalchemyenginedefault.py", line 716, in do_execute
cursor.execute(statement, parameters)
sqlalchemy.exc.IntegrityError: (sqlite3.IntegrityError) NOT NULL constraint failed: post.user_id
[SQL: UPDATE post SET user_id=? WHERE post.id = ?]
[parameters: (None, 1)]
(Background on this error at: http://sqlalche.me/e/14/gkpj)
127.0.0.1 - - [26/Apr/2021 15:00:34] "GET /product/new?__debugger__=yes&cmd=resource&f=style.css HTTP/1.1" 200 -
127.0.0.1 - - [26/Apr/2021 15:00:34] "GET /product/new?__debugger__=yes&cmd=resource&f=jquery.js HTTP/1.1" 200 -
127.0.0.1 - - [26/Apr/2021 15:00:34] "GET /product/new?__debugger__=yes&cmd=resource&f=debugger.js HTTP/1.1" 200 -
127.0.0.1 - - [26/Apr/2021 15:00:35] "GET /product/new?__debugger__=yes&cmd=resource&f=console.png HTTP/1.1" 200 -
127.0.0.1 - - [26/Apr/2021 15:00:35] "GET /product/new?__debugger__=yes&cmd=resource&f=ubuntu.ttf HTTP/1.1" 200 -
127.0.0.1 - - [26/Apr/2021 15:00:35] "GET /product/new?__debugger__=yes&cmd=resource&f=console.png HTTP/1.1" 200 -

解决方案:我把forms.py中的导入搞砸了,就像这样:

from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField, BooleanField, TextAreaField
from flask_wtf.file import FileField, FileAllowed
from wtforms.validators import DataRequired, Length, Email, EqualTo, ValidationError
from store.models import User
from flask_login import current_user

它必须重新制作成这样:

from flask_wtf import FlaskForm
from flask_wtf.file import FileField, FileAllowed
from flask_login import current_user
from wtforms import StringField, PasswordField, SubmitField, BooleanField, TextAreaField
from wtforms.validators import DataRequired, Length, Email, EqualTo, ValidationError
from store.models import User

更新:多亏了@IljaEverilä,我错了,backref可以用于分配,而不仅仅用于检索。我的回答解决了作者的问题,但我对教程代码错误的评论是不正确的,实际问题在另一个地方。有关backref的更多信息(包括assignement-SQLAlchemy文档的示例(

我把它放在那里是因为看起来上面提到的教程中的代码有一个错误。

问题是你没有通过任何user_id,但你通过了author。我检查了本教程中的代码,注意到Django模型中存在author字段,而不是Flask。因此,只需将author=current_user替换为user_id=current_user.id,它就可以工作

最新更新