You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 07:09:11