我允许用户上传CSV或Excel文件。我使用pandas读取文件并创建数据框。由于我无法预测用户将上传哪种文件类型,因此我在try / except块中包装了pd.read_csv()和pd.read_excel()。
if form.validate_on_submit():
input_filename = secure_filename(form.file.data.filename)
try:
df = pd.read_csv(form.file.data, header=0, skip_blank_lines=True, skipinitialspace=True, encoding='latin-1')
except:
df = pd.read_excel(form.file.data, header=0, skip_blank_lines=True, skipinitialspace=True, encoding='latin-1')
如果在try/except块中首先使用pd.read_csv(),并且我上传了一个.csv文件,它可以正常工作。但是如果我尝试上传一个.xlsx文件,则会出现以下错误:
TypeError: expected str, bytes or os.PathLike object, not NoneType
如果pd.read_excel()在try/except块中首先执行,并且我上传一个.xlsx文件,它就可以工作。如果我尝试上传一个.csv文件,我会得到以下错误:
pandas.io.common.EmptyDataError: No columns to parse from file
之前,我使用mimetype将文件路由到正确的pandas函数,但我希望有一个更干净(并且全面)的解决方案,不涉及多个if/elif语句。这是我的代码:
if form.file.data.mimetype == 'text/csv':
df = pd.read_csv(form.file.data, header=0, skip_blank_lines=True, skipinitialspace=True, encoding='latin-1')
elif form.file.data.mimetype == 'application/octet-stream':
df = pd.read_excel(form.file.data, header=0, skip_blank_lines=True, skipinitialspace=True, encoding='latin-1')
elif form.file.data.mimetype == 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet':
df = pd.read_excel(form.file.data, header=0, skip_blank_lines=True, skipinitialspace=True, encoding='latin-1')
else:
flash('Error Uploading File. Invalid file type. Please use xls, xlsx or csv.', 'danger')
return render_template('upload.html', current_user=current_user, form=form)
我正在使用Flask、WTForms和Python 3。谢谢。
form.file.data
是什么?如果它是类似文件的对象,是否有一种方法可以将其定位回0位置?如果没有,您可能需要将其读入类似于io.StringIO
缓冲区的东西中,该缓冲区可以被倒带。然后,在第一种类型尝试失败之前,将其定位到0。 - tdelaney