Django表单上传TXT文件调用pd.read_csv报错如何处理并存入数据库
错误原因
pd.read_csv传入字符串类型的文件内容时,默认会将该字符串识别为本地文件路径去读取,因此你传入解码后的文本内容会触发「找不到文件」的报错。- 调用
df.to_csv('log.csv', index=None)时如果传入的是本地存储路径,该方法返回值为None,后续你将None传给csv.reader也会触发逻辑错误。
解决方案
核心调整点
- 用
io.StringIO将解码后的文本内容包装为类文件对象,再传给pd.read_csv即可直接从内存读取内容,不需要落地为本地文件再读。 - 已经拿到DataFrame后不需要再转CSV重新读取,直接遍历DataFrame行写入数据库即可,减少冗余逻辑。
- 正则分隔符需要指定
engine='python'避免pandas抛出警告。
修正后完整代码
from io import StringIO import pandas as pd import json def import_csv(request): context = {} if request.method == 'POST': my_file = request.FILES['document'] # 方式1:直接用上传的文件对象读取,更省内存,适合大文件 # df = pd.read_csv(my_file, delimiter='\t+|\t\t', header=1, engine='python', encoding='utf-8') # 方式2:保留你原有的解码逻辑,用StringIO包装内容 txtData = my_file.read() html = txtData.decode('utf-8') df = pd.read_csv(StringIO(html), delimiter='\t+|\t\t', header=1, engine='python') df.rename(columns={'Type d’enregistrement': 'Type', 'Historique du taux de glucose (mg/dL)': 'GlucoseHistorique'}, inplace=True) # 列删除逻辑合并简化 drop_cols = [ 'Taux de glucose scanné (mg/dL)', 'Insuline à action rapide (sans valeur numérique)', 'Insuline à action rapide (unités)', 'Nourriture (sans valeur numérique)', 'Glucides (grammes)', 'Insuline à action lente (sans valeur numérique)', 'Insuline à action lente (unités)', 'Commentaires', 'Glycémie avec électrode de dosage (mg/dL)', 'Cétonémie (mmol/L)', 'Insuline repas (unités)', 'Insuline de correction (unités)', 'Insuline modifiée par l’utilisateur (unités)', 'Heure précédente', 'Heure mise à jour' ] df.drop(drop_cols, inplace=True, axis=1) # 保留本地存储log.csv的逻辑(如果不需要可以直接删除该行) df.to_csv('log.csv', index=None) # 直接遍历DataFrame写入数据库 for _, row in df.iterrows(): deviceDate = format_date(row[1]) Device.objects.create( patientId=1, deviceId=row[0], hour=deviceDate, type=row['Type'], glucoseValue=row['GlucoseHistorique'] ) context = { "file_content": json.dumps(txtData) } return render(request, "index.html", context=context)
内容的提问来源于stack exchange,提问作者moonzen boss
相关产品推荐
相关产品推荐

