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

如何在Python中处理SQL返回的Decimal类型数据并通过Streamlit成功下载为CSV文件

如何在Python中处理SQL返回的Decimal类型数据并通过Streamlit成功下载为CSV文件

看起来你遇到了两个核心问题:一是没法把数据库返回的字符串格式结果转换成带Decimal的有效Python对象,二是Streamlit的下载按钮没正确读取到文件内容。我来一步步帮你解决:

问题根源分析

  1. 字符串转Python对象失败:你的out是字符串类型(比如"[{A: Decimal(1,2)}]"),literal_eval不认识Decimal类型,直接用eval又因为命名空间里没导入Decimal报错。
  2. CSV写入与下载的问题:你直接用writer.writerows(out),但out是字符串,writerows会把字符串拆成单个字符逐行写入,导致CSV格式完全乱掉;而且写完文件后,文件指针停在末尾,Streamlit读取的时候就只能拿到空内容。

解决方案步骤

第一步:把字符串结果转换成真正的Python对象

首先要把数据库返回的字符串解析成带Decimal的字典列表,这里可以用eval并手动传入Decimal的命名空间:

from decimal import Decimal

# 假设out是数据库返回的字符串格式结果
out = db.run_no_throw(query, include_columns=True)
# 解析成Python对象,把Decimal传入eval的命名空间
try:
    data = eval(out, {"Decimal": Decimal})
except Exception as e:
    print(f"解析失败:{e}")
    data = []

这样就能得到真正的字典列表,每个值是Decimal类型,而不是字符串。

第二步:生成CSV内容并通过Streamlit下载

这里有两种靠谱的方式,推荐用内存流(避免本地文件的权限和指针问题):

方法一:用Pandas处理(更简洁)

现在数据已经是正确的Python对象了,Pandas可以直接处理Decimal类型,然后把DataFrame转换成CSV字符串,传给下载按钮:

import pandas as pd
import streamlit as st

if data:
    # 转换成DataFrame,Decimal会被自动处理成合适的数值类型
    df = pd.DataFrame(data)
    # 把DataFrame转换成CSV字符串
    csv_content = df.to_csv(index=False)
    # 下载按钮
    st.download_button(
        label="Download data as CSV",
        data=csv_content,
        file_name="result.csv",
        mime="text/csv"
    )

方法二:用csv模块+内存流(更灵活)

如果不想用Pandas,可以用csv模块配合io.StringIO在内存中生成CSV内容:

import csv
import io
import streamlit as st

if data:
    output = io.StringIO()
    writer = csv.writer(output, delimiter=",")
    # 写入表头(从第一个字典的键获取)
    if data:
        writer.writerow(data[0].keys())
        # 写入每行数据,Decimal会自动转成字符串
        for row in data:
            writer.writerow(row.values())
    # 把指针移到开头
    output.seek(0)
    # 下载按钮
    st.download_button(
        label="Download data as CSV",
        data=output.getvalue(),
        file_name="result.csv",
        mime="text/csv"
    )

为什么之前的代码不行?

  • 你直接对字符串out用writerows,相当于把字符串的每个字符作为一行写入,所以CSV会变成一堆零散的字符。
  • 写完本地文件后,文件指针在文件末尾,Streamlit读取的时候只能读到空内容;而且服务器上的本地文件可能不是每个请求都能正确访问到,用内存流更可靠。

备注:内容来源于stack exchange,提问作者Soumya

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 08:34:33