Azure Javascript SDK 无法为具有访问层“存档”的 Blob 复制 Blob (sync/beginCopyBlobUrl)
Posted
技术标签:
【中文标题】Azure Javascript SDK 无法为具有访问层“存档”的 Blob 复制 Blob (sync/beginCopyBlobUrl)【英文标题】:Azure Javascript SDK Fails To Copy Blob (sync/beginCopyBlobUrl) for Blob with Access Tier 'Archive' 【发布时间】: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',
,
,
【问题讨论】:
【参考方案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:\n1!r"
message = template.format(type(e).__name__, e.args)
print (message)
if __name__ == "__main__":
main("source.txt")
如果您想将 blob 保存在与源相同的容器修改目标容器中,这可以帮助您复制 blob 并将数据附加到其中。
【讨论】:
感谢您的评论 - 我使用 REST API 解决了这个问题 => ***.com/questions/69668784/…以上是关于Azure Javascript SDK 无法为具有访问层“存档”的 Blob 复制 Blob (sync/beginCopyBlobUrl)的主要内容,如果未能解决你的问题,请参考以下文章
Azure Speech javascript SDK:以 mp3 格式输出音频
Azure 信息保护/权利管理服务 SDK 2.1 - 无法启用文档跟踪
Azure,java sdk,使用ARM模板部署 - 无法转换参数文件
Azure blobs Java sdk 无法返回对象的 versionID 列表
如何使用 JavaScript v12 SDK for Browsers 检索和显示(在浏览器中)存储在 Azure 存储帐户中的多个 pdf 的 URL