Python(SQLite)开发求助:出现“object has no attribute 'get'”错误
先别慌!作为新手碰到这种问题太正常了,我来一步步帮你理清思路,先解决那个object has no attribute 'get'的错误,再帮你搭起从问卷到数据库再到结果输出的完整流程。
首先搞定那个报错:object has no attribute 'get'
这个错误说白了就是你把一个没有get()方法的对象,当成字典/字典类对象来用了。最常见的场景就是SQLite查询结果的处理:
- 默认情况下,
cursor.fetchone()或者fetchall()返回的是元组(比如('感冒', '头痛')),元组只能用索引访问(比如result[0]),不能用get()方法; - 解决办法很简单,给数据库连接设置一个字典游标,让查询结果变成支持
get()的sqlite3.Row对象:
之后再用import sqlite3 conn = sqlite3.connect('你的数据库名.db') conn.row_factory = sqlite3.Row # 关键这一行! cursor = conn.cursor()cursor.fetchone().get('字段名')就不会报错了。
另外还有一种可能:你收集的问卷答案不是字典类型,比如不小心存成了列表,却用user_answers.get('问题')来取值,这时候要确保问卷答案存在字典里(比如user_answers = {'头痛': 'Y', '恶心': 'N'})。
接下来搭建完整的实现流程
我给你梳理一个新手友好的步骤,你可以跟着改:
1. 先理清楚你的数据库结构(很重要!)
假设你现在的数据库里至少要有这几个核心表(可以根据你的实际需求调整):
-- 疾病表:存所有可能的疾病 CREATE TABLE diseases ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, -- 疾病名称 description TEXT -- 简单描述(可选) ); -- 症状表:存问卷里的所有问题 CREATE TABLE symptoms ( id INTEGER PRIMARY KEY AUTOINCREMENT, question TEXT NOT NULL -- 比如"你是否有头痛?" ); -- 症状选项-疾病关联表:存每个选项对应的疾病(一个选项可能对应多个疾病) CREATE TABLE symptom_disease_map ( id INTEGER PRIMARY KEY AUTOINCREMENT, symptom_id INTEGER, -- 关联症状表的id option_text TEXT, -- 选项内容,比如"Y"或"是" disease_id INTEGER, -- 关联疾病表的id FOREIGN KEY (symptom_id) REFERENCES symptoms(id), FOREIGN KEY (disease_id) REFERENCES diseases(id) );
如果嫌麻烦,也可以先弄个简单的单表过渡:
CREATE TABLE symptom_answers ( id INTEGER PRIMARY KEY AUTOINCREMENT, question TEXT NOT NULL, option TEXT NOT NULL, disease TEXT NOT NULL );
2. 收集问卷答案
用最简单的命令行方式收集(如果是网页/桌面表单,逻辑是一样的,只是收集方式不同):
# 示例:收集两个问题的答案 user_answers = {} user_answers["你是否有头痛?"] = input("你是否有头痛?(Y/N): ").strip().upper() user_answers["你是否有恶心呕吐?"] = input("你是否有恶心呕吐?(Y/N): ").strip().upper()
3. 连接数据库匹配疾病
这里用刚才说的字典游标,避免报错:
def get_matched_diseases(user_answers): matched_diseases = set() # 用集合避免重复疾病 with sqlite3.connect('你的数据库名.db') as conn: conn.row_factory = sqlite3.Row cursor = conn.cursor() for question, user_option in user_answers.items(): # 查询当前问题+选项对应的疾病 cursor.execute(""" SELECT d.name FROM symptoms s JOIN symptom_disease_map sd ON s.id = sd.symptom_id JOIN diseases d ON sd.disease_id = d.id WHERE s.question = ? AND sd.option_text = ? """, (question, user_option)) # 遍历查询结果,把疾病加入集合 for row in cursor.fetchall(): matched_diseases.add(row.get('name')) return matched_diseases
如果用的是单表,查询语句可以简化成:
cursor.execute("SELECT disease FROM symptom_answers WHERE question = ? AND option = ?", (question, user_option))
4. 将结果输出到文本文件
def save_result(filename="诊断结果.txt"): diseases = get_matched_diseases(user_answers) with open(filename, 'w', encoding='utf-8') as f: if diseases: f.write("根据你的问卷答案,可能的疾病如下:\n") for idx, disease in enumerate(diseases, 1): f.write(f"{idx}. {disease}\n") else: f.write("未匹配到相关疾病,建议咨询专业医生。\n") # 调用函数生成结果文件 save_result()
新手额外小提示
- 可以用DB Browser for SQLite这个可视化工具查看你的数据库,方便确认字段名和数据是否正确;
- 测试的时候多打印中间结果,比如
print(cursor.fetchall()),看看返回的是什么类型,避免踩坑; - 用
with语句管理数据库连接,不用手动关闭,更安全。
内容的提问来源于stack exchange,提问作者JBell
相关产品推荐
相关产品推荐

