Python zipfile写入在gcloud中找不到文件

Python zipfile写入在gcloud中找不到文件,python,django,gcloud,zipfile,Python,Django,Gcloud,Zipfile,我正在尝试从谷歌存储压缩一些文件 Python的zipfile在gcloud中找不到文件,只在项目中找到 如何在gcloud中查找文件 zip_buffer = io.BytesIO() with zipfile.ZipFile(zip_buffer, 'w') as zip_file: for revenue in revenues: # queryset with files a lot, so, for a each file, add in

我正在尝试从谷歌存储压缩一些文件

Python的zipfile在gcloud中找不到文件,只在项目中找到

如何在gcloud中查找文件

    zip_buffer = io.BytesIO()
    with zipfile.ZipFile(zip_buffer, 'w') as zip_file:
        for revenue in revenues:
        # queryset with files a lot, so, for a each file, add in zip
            t = tempfile.NamedTemporaryFile()
            t.write(revenue.revenue.name)
            if revenue.revenue.name:
                t.seek(0)
                with default_storage.open(revenue.revenue.name, "r") as file_data:
                    zip_file.write(file_data.name, compress_type=zipfile.ZIP_DEFLATED)
                    # the code dont pass from this part
                t.close()
    response = HttpResponse(content_type='application/x-zip-compressed')
    response['Content-Disposition'] = 'attachment; filename=my_zip.zip'
    response.write(zip_buffer.getvalue())
    return response
在本部分中,我编写了从gcloud打开的文件,但在函数内部停止:

def write(self, filename, arcname=None, compress_type=None):
    """Put the bytes from filename into the archive under the name
    arcname."""
    if not self.fp:
        raise RuntimeError(
              "Attempt to write to ZIP archive that was already closed")
    st = os.stat(filename) 
    # when I try find the file, the command os.stat search in project, not in gcloud 

“os.stat(filename)”在project中搜索文件,如何在gcloud中查找?

我将发布我的发现作为答案,因为我想对一些事情发表评论

我明白:

  • 您有一个用于处理ZIP文件的Python库
    zipfile
  • 您正在本地查找文件,并将其逐个添加到ZIP文件中
  • 对于位于谷歌云存储存储桶中的文件,您也希望这样做。但它找不到这些文件
  • 如果我误解了用例场景,请在评论中进一步阐述

    但是,如果这正是您正在尝试执行的操作,则不支持此操作。在中,声明压缩已在谷歌云存储中的文件是不可能的。这个问题的解决方案是订阅新创建的文件,然后在本地下载、压缩并在GCS中覆盖它们。如您所见,您可以列出这些文件,或者遍历存储在GCS中的文件,但您首先需要下载这些文件才能对其进行处理

    解决问题

    因此,在您的用例场景中,我建议使用Python客户端API进行以下变通:

  • 您可以使用Python API从GCS获取所有对象
  • 然后您可以使用Python API在本地下载对象
  • 只要对象位于本地目录中,您就可以使用
    zipfile
    Python库将它们压缩在一起,就像您已经在做的那样
  • 然后这些对象将被压缩,如果您不再需要下载的对象,您可以使用
    os.remove(“downloaded_file.txt”)
    删除它们
  • 如果您需要在谷歌云存储存储桶中保存压缩的ZIP文件,那么您可以使用Python API将ZIP文件上传到GCS存储桶中 如上所述,不支持直接在谷歌云存储存储桶中处理文件(例如,将文件添加到ZIP文件等)。您首先需要在本地下载它们。我希望我的解决办法能对你有所帮助

    更新

    如上所述,不支持在GCS存储桶中压缩文件。因此,我为您准备了一个关于如何使用变通方法的Python教程

    注意:因为我不擅长用Python操作os命令 图书馆和我不熟悉的
    zipfile
    library,有 可能是实现这一目标的更好、更有效的方法。然而, 可以在中找到的代码执行以下操作 程序:

    • #Public variables:
      部分将
      BUCKET_NAME
      更改为相应的BUCKET NAME,并在谷歌云Shell中执行python脚本
    • 现在我的桶结构如下:
    执行命令时,应用程序执行以下操作:

  • 将获取执行脚本的路径。e、 g.
    /home/username/myapp
  • 它将在此目录中创建一个临时目录,例如
    /home/username/myapp/temp
  • 它将遍历位于您指定的bucket中的所有文件,并在temp目录中本地下载它们。 注意:如果bucket中的文件位于目录下,它将简单地下载该文件,而不是再次创建该子目录。您可以修改代码,使其在以后按需要工作

  • 因此,新下载的文件将如下所示:
  • 之后,代码将把所有这些文件压缩到一个新的
    zipedFile.zip
    ,该文件将与您执行的
    main.py
    脚本位于同一目录中
  • 完成此步骤后,脚本将删除目录
    /home/username/myapp/temp/
    及其所有内容
  • 如上所述,在本地执行脚本后,您应该能够看到
    main.py
    zipedFile.zip
    文件,其中包含来自GCS bucket的所有压缩文件。现在,您可以根据您的项目需要采取实施的想法并对其进行修改。

    最终代码:

    zip_buffer = io.BytesIO()
    base_path = '/home/everton/compressedfiles/'
    fiscal_compentecy_month = datetime.date(int(year), int(month), 1)
    revenues = CompanyRevenue.objects.filter(company__pk=company_id, fiscal_compentecy_month=fiscal_compentecy_month)
    
    if revenues.count() > 0:
        path = base_path + str(revenues.first().company.user.pk) + "/"
        zip_name = "{}-{}-{}-{}".format(revenues.first().company.external_id, revenues.first().company.external_name, month, year)
    
        for revenue in revenues:
            filename = revenue.revenue.name.split('revenues/')[1]
            if not os.path.exists(path):
                os.makedirs(path)
            with open(path + filename, 'wb+') as file:
                file.write(revenue.revenue.read())
            file.close()
    
        with zipfile.ZipFile(zip_buffer, 'w') as zip_file:
            for file in os.listdir(path):
                zip_file.write(path + file, compress_type=zipfile.ZIP_DEFLATED)
        zip_file.close()
    
        response = HttpResponse(content_type='application/x-zip-compressed')
        response['Content-Disposition'] = 'attachment; filename={}.zip'.format(zip_name)
        response.write(zip_buffer.getvalue())
        shutil.rmtree(path)
        return response
    

    你说我的代码在gcloud中查找文件是什么意思?这里没有太多的代码可供使用。代码在项目树中搜索文件,但我需要在GCloud中进行搜索。请您更明确一点好吗?您是否在云存储桶中保存了一些文件,并希望访问它们?您是否将文件保存在Cloud Shell中并希望访问它们?或者您正在个人计算机上使用Cloud SDK并希望获取一些文件?第一个选项。我有保存在gcloud bucket中的文件,我可以阅读,但我不能的是zip。我通常会读取文件,但当我压缩文件时,Python的“zipfile”本机进程在gcloud中找不到该文件,因为它正在搜索项目,而不是gcloud.Tks man!!你的帮助非常有用!!所以,即使我可以毫不费力地从地面军事系统下载它,我也不能压缩它?为此,我需要在我的项目中下载它,然后进行压缩,好吗?那是唯一的选择?我不能这样做,如果我可以我的项目将有很多文件在您的结构。ideia与我通常下载文件时相同。我在GCS中打开了一个文件,并将其写入HttpResponse返回。我通常读取它,我的变量是一个文件,但当我使用它在ZipFile中写入时,库会在我的项目中再次搜索该文件(现在是您的帮助)
    /home/username/myapp/temp/test.txt
    /home/username/myapp/temp/test1.txt
    /home/username/myapp/temp/test2.txt
    /home/username/myapp/temp/test4.txt
    
    zip_buffer = io.BytesIO()
    base_path = '/home/everton/compressedfiles/'
    fiscal_compentecy_month = datetime.date(int(year), int(month), 1)
    revenues = CompanyRevenue.objects.filter(company__pk=company_id, fiscal_compentecy_month=fiscal_compentecy_month)
    
    if revenues.count() > 0:
        path = base_path + str(revenues.first().company.user.pk) + "/"
        zip_name = "{}-{}-{}-{}".format(revenues.first().company.external_id, revenues.first().company.external_name, month, year)
    
        for revenue in revenues:
            filename = revenue.revenue.name.split('revenues/')[1]
            if not os.path.exists(path):
                os.makedirs(path)
            with open(path + filename, 'wb+') as file:
                file.write(revenue.revenue.read())
            file.close()
    
        with zipfile.ZipFile(zip_buffer, 'w') as zip_file:
            for file in os.listdir(path):
                zip_file.write(path + file, compress_type=zipfile.ZIP_DEFLATED)
        zip_file.close()
    
        response = HttpResponse(content_type='application/x-zip-compressed')
        response['Content-Disposition'] = 'attachment; filename={}.zip'.format(zip_name)
        response.write(zip_buffer.getvalue())
        shutil.rmtree(path)
        return response