如何将Dash问卷提交的答案保存至Pandas DataFrame或数据库?
需求实现:Dash问卷答案保存至DataFrame及数据库
一、功能概述
原代码基于Dash框架实现了多选项问卷应用,点击「提交」按钮可展示答案汇总。以下修改实现:
- 将提交答案存入Pandas DataFrame
- 同步将答案与提交日期写入数据库(示例用轻量级SQLite,可扩展至其他数据库)
二、完整修改代码
from dash import Dash, html, dcc, Input, Output, State, ALL import pandas as pd from datetime import datetime import sqlite3 app = Dash(__name__) questionnaire = { 1: { 'type': 'choice', 'question': '问题1', 'options': ['-2', '-1', '+1', '+2'] }, 2: { 'type': 'choice', 'question': '问题2', 'options': ['-2', '-1', '+1', '+2'] }, 3: { 'type': 'choice', 'question': '问题3', 'options': ['-2', '-1', '+1', '+2'] }, 4: { 'type': 'choice', 'question': '问题4', 'options': ['-2', '-1', '+1', '+2'] }, } def generate(k, v): if v['type'] == 'choice': return html.Div([ html.P(f"{k}. {v['question']}"), dcc.RadioItems( id={'index': k, 'type': v['type'], 'category': 'questionnaire'}, options=[{'label': opt, 'value': opt} for opt in v['options']], required=True ) ]) app.layout = html.Div([ generate(k, v) for k, v in questionnaire.items() ] + [ html.Br(), btn := html.Button('提交', id='submit-btn'), answers := html.Div(id='answers-display'), html.Div(id='save-status', style={'marginTop': '10px', 'color': 'green'}) ]) @app.callback( Output('submit-btn', 'disabled'), Input({'category': 'questionnaire', 'type': ALL, 'index': ALL}, 'value') ) def toggle_submit(values): return any(v is None for v in values) @app.callback( [Output('answers-display', 'children'), Output('save-status', 'children')], Input('submit-btn', 'n_clicks'), [State({'category': 'questionnaire', 'type': ALL, 'index': ALL}, 'id'), State({'category': 'questionnaire', 'type': ALL, 'index': ALL}, 'value')], prevent_initial_call=True ) def collect_and_save(n_clicks, ids, answers): # 整理答案数据 answer_data = [] submit_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S') for idx, ans in zip(ids, answers): question_id = idx['index'] question_text = questionnaire[question_id]['question'] answer_data.append({ '提交时间': submit_time, '问题ID': question_id, '问题内容': question_text, '答案': ans }) # 保存到DataFrame,可选追加至本地CSV df = pd.DataFrame(answer_data) df.to_csv('问卷答案.csv', mode='a', header=False, index=False) # 保存到SQLite数据库 conn = sqlite3.connect('问卷数据库.db') df.to_sql('问卷答案表', conn, if_exists='append', index=False) conn.close() # 生成前端展示内容 display_text = html.Ul([ html.Li(f"问题{q['问题ID']}: {q['问题内容']} → 答案: {q['答案']}") for q in answer_data ]) return display_text, '答案已成功保存!' if __name__ == "__main__": app.run_server(debug=True)
三、关键修改说明
- 修复原代码问题:修正
generate函数无效判断条件,补充RadioItems的标准格式,添加必填校验 - 数据结构化:整合提交时间、问题ID、问题内容、答案为统一格式数据
- DataFrame存储:将数据转为DataFrame,支持追加写入本地CSV文件
- 数据库存储:使用SQLite自动创建数据表并追加数据,若需切换至MySQL/PostgreSQL,替换数据库连接代码即可
- 交互优化:实现提交按钮禁用逻辑(所有问题完成才启用),添加保存状态提示
四、数据库扩展示例(MySQL)
若需使用MySQL,替换数据库连接部分代码:
import pymysql conn = pymysql.connect( host='localhost', user='你的用户名', password='你的密码', db='目标数据库名' ) df.to_sql('问卷答案表', conn, if_exists='append', index=False) conn.close()
内容的提问来源于stack exchange,提问作者SebastianHeeg
相关产品推荐
相关产品推荐

