Flask查询图书出现'int/str object has no attribute id'错误求助
问题排查与解决
错误根源分析
你遇到的两个错误,核心原因是**Results类接收的数据格式不匹配**,以及数据库游标类型不一致:
- 在
search_book函数中,你使用默认游标(非字典游标)执行查询,cursor.fetchone()返回的是一个元组(比如(1, "Python入门", "张三", "978xxx", "TP311"))。当把这个元组传给Results类时,它可能会遍历元组的每个元素(比如第一个元素是int类型的id值),并尝试调用元素的id属性,自然会抛出'int object has no attribute id'错误;如果只查询字符串类型字段,元组第一个元素是字符串,就会抛出'str object has no attribute id'错误。 - 对比
users函数,你使用了pymysql.cursors.DictCursor,cursor.fetchall()返回的是字典列表(每个元素是{"id":1, "title":"Python入门", ...}),Results类可以正确识别字典中的键值对,所以没有报错。
修复步骤
1. 统一使用字典游标
在search_book函数中,创建游标时指定DictCursor,确保查询结果返回字典格式:
cursor = conn.cursor(pymysql.cursors.DictCursor)
2. 修正参数元组的写法
data = (_title) 并不是元组(单个元素的元组必须加逗号),会导致SQL执行时参数不匹配,改成:
data = (_title,)
3. 调整代码逻辑,确保flash消息正常执行
flash('Successful search!') 写在return语句之后,永远不会被执行,需要移到return前面:
flash('Successful search!') return render_template('books.html', table=table)
4. 完善资源关闭逻辑,避免空指针错误
在finally块中,先判断cursor和conn是否存在,再执行关闭操作,防止初始化失败时报错:
finally: if cursor: cursor.close() if conn: conn.close()
修复后的完整search_book函数
@app.route('/search', methods=['POST']) def search_book(): conn = None cursor = None try: _title = request.form['inputTitle'] if _title and request.method == 'POST': sql = "SELECT * FROM books WHERE title=%s" data = (_title,) conn = mysql.connect() cursor = conn.cursor(pymysql.cursors.DictCursor) cursor.execute(sql, data) row = cursor.fetchone() # 处理查询不到结果的情况 if not row: flash('No books found matching the title!') return redirect(url_for('search_view')) # 将单个查询结果包装成列表,适配Results类的参数要求 table = Results([row]) table.border = True flash('Successful search!') return render_template('books.html', table=table) else: return 'Error while searching for book' except Exception as e: print(e) flash(f'Search failed: {str(e)}') return redirect(url_for('search_view')) finally: if cursor: cursor.close() if conn: conn.close()
额外注意事项
- 当
cursor.fetchone()返回None(没有匹配的图书)时,直接传给Results可能会引发新的错误,需要提前判断并处理这种情况,比如跳转回搜索页面并提示用户。
内容的提问来源于stack exchange,提问作者user3829969
相关产品推荐
相关产品推荐

