[譯] 使用 AWS Ruby SDK v2 更新 S3 物件 Metadata
From: Updating S3 Object Metadata With the AWS Ruby SDK v2
Author: Matt
posted at: 2017/5/31
今天我在 S3 就如同在玩火一樣 - 弄壞了一個網站. 我做了研究,徹底的測試了我的程式碼,接著按下了 enter. 之後沒多久,我的心掉落的和我的網站掛掉的速度一樣快。我決定寫下一篇速記來防止同樣的錯誤發生在其他人身上。
S3 不是資料庫
不可能在 S3 中做到「更新」資料庫 - 在S3並沒有更新資料的方法。這在 Ruby SDK 與 AWS CLI 之中都是成立的。如果你項我一樣在找尋更新整個 Bucket 的物件來更新 metadata (舉例來說: 像是名為 Cache-Control
的 headers),你將會需要使用 copy_to
方法。
讓我們開始認證和攫取我們的 bucket。
1 |
|
現在我們可以透過每一個物件和複製它自己並且帶上一些新的 metadata. 注意我們使用 option metadata_directive: 'REPLACE'
- 這個將會以新的 metadata 取代物件原有的 metadata。如果缺少它,我們將無法複製任何新的,而且會得到錯誤訊息如下:
1 |
|
然而,取代 metadata 將會取代其它屬於這個物件的所有東西,例如: 權限(permission). 請勿執行以下的程式碼。
1 |
|
這是我所搞砸的。我更新的所有的 S3 物件因為缺少了讀的權限(read permissions),接著 CDN 不再可以存取這些資料。現在看起來是一個很蠢的錯誤,但當時我對出錯的狀況沒有任何頭緒。
更新 / 複製物件並且保留原有的資訊
讓我們再試一次;這次我們確保 request 包含(include)所有物件的欄位。這邊是一個可能的選項清單( list of possible options),用途是傳送到 copy_to
方法。
1 |
|
用這個 List 武裝之後,我們抓取所有存在的資料並且 merge 到新的 option hash。我只想要加上驗證 (valid) 選項而不是使用 get
取得所有資訊,所以我使用 Array#slice
來對之前的清單做處理。
也需要注意的是,我使用在下面 object_summary.get
- 這是因為物件的摘要並不包含 metadata, permission … 之類的東西。這會造成額外的開銷,但是此時我不確定還有其他任何方法可以達到同樣的目的。
1 |
|
如果你的 bucket 的大小很大,這會用到一些時間。然而,你得知道 copy_to
方法發出請求至 S3 和不會從你的本地端上傳任何的資料。所以即使你複製到新的位置,你也不會重新上傳檔案。
這邊是完整的程式碼:
1 |
|
最後
如果你覺得這對你有幫助, 請 tweet @atMattb。謝謝閱讀。