Flask-SQLAlchemy多查询更新行值报错:List对象无id属性
问题描述
尝试更新feedback表中studentEntry列等于studentTimetable对应行id的score值时,触发错误:List object has no attribute 'id'
表结构代码
class studentTimetable(UserMixin, db.Model): __tablename__ = 'studentTimetable' id = db.Column(db.Integer, primary_key=True, nullable=False, autoincrement=True) SACE_no = db.Column(db.String(100), db.ForeignKey('student.SACE_no'), unique=False, nullable=False) subject = db.Column(db.String(100), db.ForeignKey('courses.name'), nullable=False) checkpoint = db.relationship('feedback', backref='studentTimetable',lazy=True) def __repr__(self): return '<User %r>' % self.SACE_no def to_dict(self): return { 'id': self.id, 'subject': self.subject, 'SACE_no': self.SACE_no, } class feedback(UserMixin, db.Model): __tablename__ = 'feedback' id = db.Column(db.Integer, primary_key=True, autoincrement=True, nullable=False) studentEntry = db.Column(db.Integer, db.ForeignKey('studentTimetable.id'), nullable=False) score = db.Column(db.Integer) def __repr__(self): return '<User %r>' % self.id def to_dict(self): return { 'id': self.id, 'studentEntry': self.studentEntry, 'score': self.score, }
执行代码
@login_required @app.route('/dashboard/<subject>/<sace>', methods=['GET', 'POST']) def studentEdit(subject, sace): if request.method == 'POST': assessment = float(request.form.get('assessments')) attendance = float(request.form.get('attendance')) focus = float(request.form.get('focus')) print(focus) totalCheckpoint = float(assessment+attendance+focus) rowId = studentTimetable.query.filter_by(subject=subject, SACE_no=sace).all() checkpointUpdate = feedback.query.filter_by(studentEntry=rowId.id).first() checkpointUpdate.score = totalCheckpoint db.session.commit() '''for i in rowId: rowId = i.to_dict() print(rowId['id'])''' return render_template('students.html', subject=subject) return render_template('edit.html')
问题根源与修复方案
- 错误原因:
studentTimetable.query.filter_by(...).all()返回的是查询结果列表,不是单个数据库对象,因此无法直接通过rowId.id获取属性值。 - 修复方案:
- 若确定该查询只会返回一条数据,改用
.first()替代.all(),直接获取单个对象:row = studentTimetable.query.filter_by(subject=subject, SACE_no=sace).first() if row: # 先判断是否查询到数据,避免空对象报错 checkpoint = feedback.query.filter_by(studentEntry=row.id).first() if checkpoint: checkpoint.score = totalCheckpoint db.session.commit() - 若可能返回多条数据,需要遍历列表处理每一条记录:
rows = studentTimetable.query.filter_by(subject=subject, SACE_no=sace).all() for row in rows: checkpoint = feedback.query.filter_by(studentEntry=row.id).first() if checkpoint: checkpoint.score = totalCheckpoint db.session.commit()
- 若确定该查询只会返回一条数据,改用
- 额外提示:添加空值判断,避免因查询不到数据触发
AttributeError,提升代码健壮性。
内容的提问来源于stack exchange,提问作者Sxnn
相关产品推荐
相关产品推荐

