【问题标题】:Azure Javascript SDK Fails To Copy Blob (sync/beginCopyBlobUrl) for Blob with Access Tier 'Archive'Azure Javascript SDK 无法为具有访问层“存档”的 Blob 复制 Blob (sync/beginCopyBlobUrl)
【发布时间】:2021-12-10 13:20:10
【问题描述】:

我正在使用 Node.js 和 Azure SDK v12。我想复制具有访问层==='Archive 的现有 blob。为此,我想复制 blob 并将其写入具有不同 blob 名称和更改(重新水化)访问层的同一容器。

我可以直接更改现有“存档”blob 的访问层,但这不是我的目标。我想保留访问层为“存档”的 blob,并创建一个访问层==="Cool 的新 blob " || "热"。

我正在按照文档 (https://docs.microsoft.com/en-us/azure/storage/blobs/archive-rehydrate-overview) 进行操作。

如果 blob 具有访问层==='Cool' ||,则以下代码有效'热的'。但是,对于访问层 ==='Archive' 的 blob,它会失败。

另外:我认为 SDK 的“syncCopyFromUrl”和“beginCopyFromUrl”不适用于复制访问层 ===“存档”的 blob。如果我尝试这样做,我会收到以下错误:对于“syncCopyFromUrl”,它给了我:“在存档的 blob 上不允许执行此操作。”对于“beginCopyFromUrl”,它给了我:“复制源 blob 已被修改” - 当我检查时,该 blob 没有被修改(我检查最后修改日期,它是过去的)。

如何复制存档的 blob 并将新 blob 保存在具有不同访问类型的同一容器中

const { BlobServiceClient,generateBlobSASQueryParameters, BlobSASPermissions } = require("@azure/storage-blob");

export default async (req, res) => {
    if (req.method === 'POST') {
      
      const connectionString = 'DefaultEndpointsProtocol=...'
      const containerName = 'container';

      const srcFile='filename' // this is the filename as it appears on Azure portal (i.e. the blob name)
      
      async function getSignedUrl(blobClient, options={}){

          options.permissions = options.permissions || "racwd"
          const expiry = 3600;
          const startsOn = new Date();
          const expiresOn = new Date(new Date().valueOf() + expiry * 1000);
        
        
          const token = await generateBlobSASQueryParameters(
              {
                  containerName: blobClient.containerName,
                  blobName: blobClient.name,
                  permissions: BlobSASPermissions.parse(options.permissions),
                  startsOn, // Required
                  expiresOn, // Optional
              },
              blobClient.credential,
          );
      
          return `${blobClient.url}?${token.toString()}`;
      }
      
      (async () => {
          try {
              const blobServiceClient = BlobServiceClient.fromConnectionString(connectionString);
              const containerClient = blobServiceClient.getContainerClient(containerName);
              const sourceBlobClient = containerClient.getBlockBlobClient(srcFile);
              const targetBlobClient = containerClient.getBlockBlobClient('targetFileName');
      
              const url = await getSignedUrl(sourceBlobClient);
              console.log(`source: ${url}`);
              
              const result = await targetBlobClient.syncCopyFromURL(url);
              // const result = await targetBlobClient.beginCopyFromURL(url);
              
              console.log(result)
          } catch (e) {
              console.log(e);
          }
      })();
    }
}

export const config = {
    api: {
      bodyParser: {
        sizeLimit: '1gb',
      },
    },
}

【问题讨论】:

    标签: node.js azure sdk copy blob


    【解决方案1】:

    我们需要知道的主要步骤是更改 blob 的访问层。

    通过下面的代码,我们可以从 JS 设置访问层:

      // Archive the blob - Log the error codes
          await blockBlobClient.setAccessTier("Archive");
          try {
            // Downloading an archived blockBlob fails
            console.log("// Downloading an archived blockBlob fails...");
            await blockBlobClient.download();
          } catch (err) {
            // BlobArchived Conflict (409)  This operation is not permitted on an archived blob.
            console.log(
              `requestId - ${err.details.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}`
            );
            console.log(`error message - ${err.details.message}\n`);
          }
    

    其余的操作可以在复制事件的帮助下完成,如下所示:

    import logging
    import sys
    import os
    import azure.functions as func
    from azure.storage import blob
    from azure.storage.blob import BlobServiceClient, BlobClient, ContainerClient, __version__
    
    def main(myblob: func.InputStream):
        try:
            logging.info(f"Python blob trigger function processed blob \n")
            CONN_STR = "ADD_CON_STR"
            blob_service_client = BlobServiceClient.from_connection_string(CONN_STR)
    
            # MAP SOURCE FILE
            blob_client = blob_service_client.get_blob_client(container="newcontainer0805", blob="source.txt")
    
            #SOURCE CONTENTS
            content =  blob_client.download_blob().content_as_text
            
            # WRITE HEADER TO A OUT PUTFILE
            output_file_dest = blob_service_client.get_blob_client(container="target", blob="target.csv")
            
            #INITIALIZE OUTPUT               
            output_str = ""
            
            #STORE COULMN HEADERS
            data= list()
                
            data.append(list(["column1", "column2", "column3", "column4"]))
            output_str += ('"' + '","'.join(data[0]) + '"\n')
            output_file_dest.upload_blob(output_str,overwrite=True)
            logging.info(' END OF FILE UPLOAD')
        except Exception as e:
            template = "An exception of type {0} occurred. Arguments:\n{1!r}"
            message = template.format(type(e).__name__, e.args)
            print (message)
    if __name__ == "__main__":
        main("source.txt")
    

    如果您想将 blob 保存在与源相同的容器修改目标容器中,这可以帮助您复制 blob 并将数据附加到其中。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-01-04
    • 2021-09-17
    • 1970-01-01
    • 2019-03-20
    • 2020-10-26
    • 1970-01-01
    • 1970-01-01
    • 2018-09-14
    相关资源
    最近更新 更多