この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
DA事業本部の森脇です。
先日業務の中で、このような状況に出くわしました。
...同名のS3オブジェクトが存在している!?
同じ名前のオブジェクトは1つしか存在しないため、何かがおかしいです。
こんな場合、以下のケースに当てはまるかもしれません。
1.名前の前後に空白が存在する
オブジェクト名の前後に空白が存在しているため、同名のように見えてしまっているかもしれません。 pythonを使い、空白が無いか確認してみましょう。
(pythonのバージョンは3.7を使用してます)
ソースコード:
import boto3
s3 = boto3.resource("s3")
bucketname = "xxx-bucket"
prefix = "data/"
for o in s3.Bucket(bucketname).objects.filter(Prefix=prefix).all():
if o.key.endswith("/"):
continue
print(f"@@@{o.key}@@@")
実行結果:
% python3 /tmp/dup-check.py
@@@data/sample.dat@@@
@@@data/sample.dat @@@
実行結果から、片方のオブジェクトには末尾に空白が入っていることがわかりました。
(厳密には同名のオブジェクトではありませんが、パッと見で気づかない例だと思います)
2.オブジェクト名が別のUnicode正規化で表現されている
オブジェクト名にマルチバイト文字が含まれる場合、異なるUnicode正規化で命名されているかもしれません。 pythonのコードを使って、バイトコードで表示してみます。
現象:
ソースコード:
import boto3
s3 = boto3.resource("s3")
bucketname = "xxx-bucket"
prefix = "data2/"
for o in s3.Bucket(bucketname).objects.filter(Prefix=prefix).all():
key = o.key
if key.endswith("/"):
continue
print(f"@@{key}@@@")
print(key.encode())
実行結果:
% python3 /tmp/dup-check2.py
@@data2/データ1.dat@@@
b'data2/\xe3\x83\x86\xe3\x82\x99\xe3\x83\xbc\xe3\x82\xbf1.dat'
@@data2/データ1.dat@@@
b'data2/\xe3\x83\x87\xe3\x83\xbc\xe3\x82\xbf1.dat'
単純なprint文だと全く同じように見えますが、バイトコードで表現すると違いがわかりますね。
このケースでは、同じオブジェクト名に対して"NFC","NFD"にて正規化された名前がついていました。
まとめ
私が実際に遭遇したのは(2)の方でした。
同じ現象が発生した方の助けになれば幸いです。