Python Sqlalchemy:InvalidRequestError:Object'&书信电报;位于0x3a970d0的用户>';已附加到会话';2';(这是';3';)
我正在修改一个烧瓶应用程序。我正在尝试添加电子邮件授权 我的用户模型在屏幕截图中,并且:Python Sqlalchemy:InvalidRequestError:Object'&书信电报;位于0x3a970d0的用户>';已附加到会话';2';(这是';3';),python,flask,sqlalchemy,flask-sqlalchemy,Python,Flask,Sqlalchemy,Flask Sqlalchemy,我正在修改一个烧瓶应用程序。我正在尝试添加电子邮件授权 我的用户模型在屏幕截图中,并且: class User(UserMixin, SurrogatePK, Model): __tablename__ = 'users' username = Column(db.String(80), nullable=True) email = Column(db.String(80), nullable=False) #: The hashed password
class User(UserMixin, SurrogatePK, Model):
__tablename__ = 'users'
username = Column(db.String(80), nullable=True)
email = Column(db.String(80), nullable=False)
#: The hashed password
password = Column(db.String(128), nullable=True)
created_at = Column(db.DateTime, nullable=False, default=dt.datetime.utcnow)
first_name = Column(db.String(30), nullable=True)
last_name = Column(db.String(30), nullable=True)
active = Column(db.Boolean(), default=False)
admin = Column(db.Boolean(), default=False)
confirmed = db.Column(db.Boolean, default=False)
confirmed_on = db.Column(db.DateTime, nullable=True)
def __init__(self, username=username, email=email, password=None, **kwargs):
db.Model.__init__(self, username=username, email=email, **kwargs)
if password:
self.set_password(password)
else:
self.password = None
def set_password(self, password):
self.password = bcrypt.generate_password_hash(password)
作为注册过程的一部分,我从表单接收电子邮件,并对其进行处理,从表单创建令牌并创建用户,然后使用以下方式向电子邮件发送确认电子邮件:
@blueprint.route("/get_email/", methods=['GET', 'POST'])
def get_email():
form = EmailForm(request.form, csrf_enabled=False)
if form.validate_on_submit():
new_user = User.create(username=None,email=form.email.data)
token = generate_confirmation_token(form.email.data)
confirm_url = url_for('user.confirm_email', token=token, _external=True)
html = render_template('users/activate.html', confirm_url=confirm_url)
subject = "Please confirm your email"
send_email(form.email.data, subject, html)
return redirect(url_for("main.home"))
在这种情况下,我发送了一封电子邮件至:
cluemarine5@mailinator.com
该电子邮件包含一个确认链接,如下所示:
http://127.0.0.1:5000/users/confirm/ImNsdWVtYXJpbmU1QG1haWxpbmF0b3IuY29tIg.CZ-urA.n5IErF0CPPG6EnIwJeSP6mPmDb4
其中包含嵌入电子邮件的cluemarine5@mailinator.com”“在代币上
要确认,请单击激活以下路线的链接:
@blueprint.route('/confirm/<token>')
def confirm_email(token):
try:
email = confirm_token(token)
except:
flash('The confirmation link is invalid or has expired.', 'danger')
user = User.query.filter_by(email=email).first_or_404()
if user.confirmed:
flash('Account already confirmed. Please login.', 'success')
else:
user.confirmed = True
user.confirmed_on = datetime.datetime.now()
db.session.add(user)
db.session.commit()
flash('You have confirmed your account. Thanks!', 'success')
return redirect(url_for('main.home'))
然后我得到上面的错误。我做错了什么?我终于意识到这个cookiecutter使用了一个名为“CRUDMixin”的类来进行db操作,它位于database.py中:
class CRUDMixin(object):
"""Mixin that adds convenience methods for CRUD (create, read, update, delete)
operations.
"""
@classmethod
def create(cls, **kwargs):
"""Create a new record and save it the database."""
instance = cls(**kwargs)
return instance.save()
def update(self, commit=True, **kwargs):
"""Update specific fields of a record."""
for attr, value in kwargs.iteritems():
setattr(self, attr, value)
return commit and self.save() or self
def save(self, commit=True):
"""Save the record."""
db.session.add(self)
if commit:
db.session.commit()
return self
def delete(self, commit=True):
"""Remove the record from the database."""
db.session.delete(self)
return commit and db.session.commit()
class Model(CRUDMixin, db.Model):
"""Base model class that includes CRUD convenience methods."""
__abstract__ = True
然后我改变了:
db.session.add(user)
db.session.commit()
致:
它在确认电子邮件中开始工作,您不需要执行db.session.add(用户)-当您执行查询时,它会添加到会话中。感谢您的帮助。
db.session.add(user)
db.session.commit()
use.save()