S3 boto列表键有时会返回目录键

Ste*_*lin 13 python amazon-s3 boto amazon-web-services

我注意到boto的api返回值取决于存储桶位置.我有以下代码:

con = S3Connection(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY)
bucket = con.get_bucket(S3_BUCKET_NAME)
keys = bucket.list(path)
for key in keys:
  print key
Run Code Online (Sandbox Code Playgroud)

我在两个桶中运行,一个在美国西部,另一个在爱尔兰.这个桶中的路径是一个子目录,对爱尔兰我得到子目录和下面的任何键,对我们西方我只得到下面的键.

所以爱尔兰给出:

<Key: <bucketName>,someDir/>
<Key: <bucketName>,someDir/someFile.jpg>
<Key: <bucketName>,someDir/someOtherFile.jpg>
Run Code Online (Sandbox Code Playgroud)

美国标准给出的地方:

<Key: <bucketName>,someDir/someFile.jpg>
<Key: <bucketName>,someDir/someOtherFile.jpg>
Run Code Online (Sandbox Code Playgroud)

显然,无论存储桶位置如何,我都希望能够编写相同的代码.任何人都知道我可以做些什么来解决这个问题,所以我得到了同样可预测的结果.或者即使它导致问题或S3.我注意到在爱尔兰有一个不同的命名桶的政策,不同的本地人有自己的api版本吗?

谢谢,

史蒂夫

Ste*_*lin 18

感谢Steffen,他建议查看如何创建密钥.经过进一步的调查,我想我已经掌握了这里发生的事情.我与水桶区域相连的原始位置是红鲱鱼.它似乎是由于管理控制台在操作密钥时所执行的操作.

如果在管理控制台中创建目录,则会创建一个0字节密钥.执行列表时将返回此信息.

如果您使用boto创建/上传文件,则它不会创建该文件夹.有趣的是,如果从文件夹中删除文件(从AWS控制台),则会为用于包含密钥的文件夹创建密钥.如果您然后使用boto再次上传bey,那么您在UI中具有完全相同的外观结构,但实际上您有一个虚假的附加密钥用于该目录.这就是我发生的事情,因为我正在测试我的应用程序,我正在清除密钥,然后找到不同的结果.

值得知道这发生了.UI中没有指示器显示文件夹是创建的文件夹(一个将作为键返回的文件夹)还是解释的文件夹(基于键名称).


Ste*_*pel 6

我对你的问题没有明确的答案,但至少可以抛出一些部分答案:

背景

目录/文件夹模拟

Amazon S3实际上没有文件夹/目录的原生概念,而是仅由存储桶和对象/键组成的平面存储架构 - 在S3的大多数工具(包括AWS管理控制台本身)中看到的目录样式表示基于仅仅基于约定,即模拟具有相同前缀的对象的层次结构 - 请参阅我如何指定与目录不匹配的对象到期前缀的答案?有关此体系结构的更多详细信息,包括AWS文档中的引用/引用.

每个地区的API差异

我注意到在爱尔兰有一个不同的命名桶的政策,不同的本地人有自己的api版本吗?

对于Amazon S3而言,这显然确实如此,这是他们最早的产品之一,请参阅例如Bucket Restrictions and Limitations:

在除美国标准区域以外的所有区域中,在命名存储桶时必须使用以下准则.[...] [强调我的]

美国标准区域的这些细节也可以在S3文档的其他地方看到,而美国标准本身就是一个不同寻常的结构,与其他明显受地理限制的区域相比:

美国标准 - 在美国使用Amazon S3服务器

这是默认区域.美国标准区域使用网络地图自动将请求路由到北弗吉尼亚州或太平洋西北地区的设施.要使用此区域,请在控制台中创建存储桶时选择US Standard作为区域.美国标准区域为所有请求提供最终一致性.[强调我的]

这种隐含的CDN行为对于此默认的S3区域(即美国标准)是唯一的,而在我认为的任何其他AWS服务上都看不到.

可能的原因

我有一个微弱的S3内存实际上将零字节对象/密钥放入更近期区域(即除美国标准以外的所有模拟目录/文件夹)的存储桶中,而美国标准区域的传统解决方案可能会有所不同,例如,简单地基于已建立的目录分离命名约定,/并且完全省略专用对象/密钥.

解

如果分析是正确的,那么除了为这两种情况保留单独的代码路径之外,你无能为力,我担心

祝好运!


Dan*_*nas 5

我遇到了同样的问题.作为解决方法,您可以使用尾部过滤掉所有键'/'以消除"目录"条目.

def files(keys):
    return (key for key in keys if not key.name.endswith('/'))

s3 = boto.connect_s3(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY)
bucket = s3.get_bucket(S3_BUCKET_NAME)
keys = bucket.list(path)
for key in files(keys):
    print(key)
Run Code Online (Sandbox Code Playgroud)