Распаковка gzipped данных из multipart/form-data с помощью django
У меня довольно много проблем при попытке распаковать gzipped данные в django. Я попробовал несколько решений, предложенных в Скачать и распаковать gzipped файл в памяти?, но мне кажется, что я столкнулся с трудностями в том, как это взаимодействует с Django
Я хотел бы иметь возможность загрузить data.csv.gz
и затем, если это gzip, извлечь сжатые данные в django File
, чтобы продолжить свой путь (сохранение в FileField
)
Что у меня есть на данный момент в моем сериализаторе
def create(self, validated_data):
file: File = validated_data.get("file")
ext = file.name.split(".")[-1].lower()
if ext == "gz":
compressedFile = io.BytesIO()
compressedFile.write(file.read())
decompressed_fname = file.name[:-3]
decompressedFile = gzip.GzipFile(fileobj=compressedFile)
with open(decompressed_fname, "wb") as outfile:
outfile.write(decompressedFile.read())
with open(decompressed_fname, "rb") as outfile:
file = File(outfile)
ext = decompressed_fname.split(".")[-1].lower()
...
Когда я делаю это, outfile пуст, когда я проверяю его содержимое на диске, и выдает ошибку в последующих процедурах
f.seek(0)
ValueError: seek of closed file
Я получаю аналогичную ошибку, если вместо этого использую shutil
if ext == "gz":
compressedFile = io.BytesIO()
compressedFile.write(file.read())
decompressed_fname = file.name[:-3]
import shutil
shutil.copyfileobj(gzip.GzipFile(fileobj=file), open(decompressed_fname, "wb"))
with open(decompressed_fname, "rb") as outfile:
file = File(outfile)
ext = decompressed_fname.split(".")[-1].lower()
команда curl, которую я использую:
curl http://0.0.0.0:8000/upload/ -X 'POST' -H "Content-Encoding: gzip" -F "input_type=data" -F "file=@data.csv.gz"
Я заставил его работать следующим образом:
if ext == "gz":
compressed_file = file.open()
decompressed_fname = file.name[:-3]
decompressedFile = gzip.GzipFile(fileobj=compressed_file)
f = io.BytesIO()
f.write(decompressedFile.read())
file = File(f, name=decompressed_fname)
ext = decompressed_fname.split(".")[-1].lower()
проблема была в том, что файл является InMemoryUploadedFile
и должен быть сначала открыт. Хотя я не совсем понимаю