如何在 "rb" 模式下使用 csv 模块读取 csv 文件的 headers?
How to read the headers of a csv file using csv module in "rb" mode?
我目前正在 "rb"
模式下读取 csv 文件并将文件上传到 s3 存储桶。
with open(csv_file, 'rb') as DATA:
s3_put_response = requests.put(s3_presigned_url,data=DATA,headers=headers)
所有这些都工作正常,但现在我必须在进行 put 调用之前验证 csv 文件中的 headers。
当我在下面尝试 运行 时,出现错误。
with open(csv_file, 'rb') as DATA:
csvreader = csv.reader(file)
columns = next(csvreader)
# run-some-validations
s3_put_response = requests.put(s3_presigned_url,data=DATA,headers=headers)
这抛出
_csv.Error: iterator should return strings, not bytes (did you open the file in text mode?)
作为解决方法,我创建了一个新函数,它以 "r"
模式打开文件并对 csv headers 进行验证,这工作正常。
def check_csv_headers():
with open(csv_file, 'r') as file:
csvreader = csv.reader(file)
columns = next(csvreader)
我不想读取同一个文件两次。一次用于 header 验证,一次用于上传到 s3。如果我在 "r"
模式下上传,上传部分也不起作用。
有什么方法可以在 "rb"
模式下只读取一次文件来实现这一点?我必须使用 csv
模块而不是 pandas
库来完成这项工作。
做你想做的事是可能的,但效率不高。简单地打开一个文件并不那么昂贵。 CSV reader 一次只读取一行,而不是整个文件。
要做你想做的事你必须:
- 以字节形式读取第一行
- 解码成字符串(使用正确的编码)
- 将其转换为字符串列表
- 用
csv.reader
解析它,最后
- 定位到流的开头。
否则,您最终将只上传没有 headers 的数据:
with open(csv_file, 'rb') as DATA:
header=file.readline()
lines=[header.decode()]
csvreader = csv.reader(lines)
columns = next(csvreader)
// run-some-validations
DATA.seek(0)
s3_put_response = requests.put(s3_presigned_url,data=DATA,headers=headers)
以文本形式打开文件不仅更简单,还允许您将验证逻辑与上传代码分开。
要确保一次只读取一行,您可以使用 buffering=1
def check_csv_headers():
with open(csv_file, 'r', buffering=1) as file:
csvreader = csv.reader(file)
columns = next(csvreader)
// run-some-validations
with open(csv_data, 'rb') as DATA:
s3_put_response = requests.put(s3_presigned_url,data=DATA,headers=headers)
或
def check_csv_headers():
with open(csv_file, 'r', buffering=1) as file:
csvreader = csv.reader(file)
columns = next(csvreader)
// run-some-validations
//If successful
return True
def upload_csv(filePath):
if check_csv_headers(filePath) :
with open(csv_data, 'rb') as DATA:
s3_put_response = requests.put(s3_presigned_url,data=DATA,headers=headers)
我目前正在 "rb"
模式下读取 csv 文件并将文件上传到 s3 存储桶。
with open(csv_file, 'rb') as DATA:
s3_put_response = requests.put(s3_presigned_url,data=DATA,headers=headers)
所有这些都工作正常,但现在我必须在进行 put 调用之前验证 csv 文件中的 headers。
当我在下面尝试 运行 时,出现错误。
with open(csv_file, 'rb') as DATA:
csvreader = csv.reader(file)
columns = next(csvreader)
# run-some-validations
s3_put_response = requests.put(s3_presigned_url,data=DATA,headers=headers)
这抛出
_csv.Error: iterator should return strings, not bytes (did you open the file in text mode?)
作为解决方法,我创建了一个新函数,它以 "r"
模式打开文件并对 csv headers 进行验证,这工作正常。
def check_csv_headers():
with open(csv_file, 'r') as file:
csvreader = csv.reader(file)
columns = next(csvreader)
我不想读取同一个文件两次。一次用于 header 验证,一次用于上传到 s3。如果我在 "r"
模式下上传,上传部分也不起作用。
有什么方法可以在 "rb"
模式下只读取一次文件来实现这一点?我必须使用 csv
模块而不是 pandas
库来完成这项工作。
做你想做的事是可能的,但效率不高。简单地打开一个文件并不那么昂贵。 CSV reader 一次只读取一行,而不是整个文件。
要做你想做的事你必须:
- 以字节形式读取第一行
- 解码成字符串(使用正确的编码)
- 将其转换为字符串列表
- 用
csv.reader
解析它,最后 - 定位到流的开头。
否则,您最终将只上传没有 headers 的数据:
with open(csv_file, 'rb') as DATA:
header=file.readline()
lines=[header.decode()]
csvreader = csv.reader(lines)
columns = next(csvreader)
// run-some-validations
DATA.seek(0)
s3_put_response = requests.put(s3_presigned_url,data=DATA,headers=headers)
以文本形式打开文件不仅更简单,还允许您将验证逻辑与上传代码分开。
要确保一次只读取一行,您可以使用 buffering=1
def check_csv_headers():
with open(csv_file, 'r', buffering=1) as file:
csvreader = csv.reader(file)
columns = next(csvreader)
// run-some-validations
with open(csv_data, 'rb') as DATA:
s3_put_response = requests.put(s3_presigned_url,data=DATA,headers=headers)
或
def check_csv_headers():
with open(csv_file, 'r', buffering=1) as file:
csvreader = csv.reader(file)
columns = next(csvreader)
// run-some-validations
//If successful
return True
def upload_csv(filePath):
if check_csv_headers(filePath) :
with open(csv_data, 'rb') as DATA:
s3_put_response = requests.put(s3_presigned_url,data=DATA,headers=headers)