我注意到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
我在两个桶中运行,一个在美国西部,一个在爱尔兰。这个桶中的路径是一个子目录,对爱尔兰我得到子目录和下面的任何键,对我们西方我只得到下面的键。
所以爱尔兰给出了:
<Key: <bucketName>,someDir/>
<Key: <bucketName>,someDir/someFile.jpg>
<Key: <bucketName>,someDir/someOtherFile.jpg>
美国标准给出的地方:
<Key: <bucketName>,someDir/someFile.jpg>
<Key: <bucketName>,someDir/someOtherFile.jpg>
显然,无论存储桶位置如何,我都希望能够编写相同的代码。任何人都知道我可以做些什么来解决这个问题,所以我得到了同样可预测的结果。或者即使它导致问题或S3。我注意到在爱尔兰有一个不同的命名桶的政策,不同的当地人有自己的api版本吗?
谢谢,
史蒂夫
答案 0 :(得分:18)
感谢Steffen,他建议查看如何创建密钥。经过进一步的调查,我想我已经掌握了这里发生的事情。我与水桶区域相连的原始位置是红鲱鱼。它似乎是由于操作密钥时管理控制台的作用。
如果在管理控制台中创建目录,则会创建一个0字节密钥。执行列表时将返回此信息。
如果您使用boto创建/上传文件,则它不会创建该文件夹。有趣的是,如果从文件夹中删除文件(从AWS控制台),则会为用于包含密钥的文件夹创建密钥。如果您然后使用boto再次上传bey,那么您在UI中具有完全相同的外观结构,但实际上您有一个虚假的附加密钥用于该目录。这就是我发生的事情,因为我正在测试我的应用程序,我正在清理密钥然后找到不同的结果。
值得知道这种情况发生。 UI中没有指示器显示文件夹是创建文件夹(一个将作为键返回)还是解释文件夹(基于键名称)。
答案 1 :(得分:6)
我对你的问题没有明确的答案,但至少可以抛出一些部分答案:
Amazon S3实际上没有文件夹/目录的原生概念,而是仅由桶和对象/键组成的平面存储架构 - 在S3的大多数工具中看到的目录样式表示(包括{ {3}}本身完全基于约定,即模拟具有相同前缀的对象的层次结构 - 有关此体系结构的更多详细信息,请参阅我对AWS Management Console的回答,包括来自AWS文档的引用/引用。
我注意到在爱尔兰有一个不同的命名桶的政策, 不同的当地人有自己的api版本吗?
How to specify an object expiration prefix that doesn't match the directory?显然确实如此,这是他们最早的产品之一,例如Amazon S3:
在除<美国标准区域之外的所有地区,您必须使用 命名存储桶时遵循以下准则。 [...] [强调我的]
美国标准区域的这些细节也可以在Bucket Restrictions and Limitations的其他地方看到,而美国标准本身就是一个不寻常的结构。否则明显受地理限制S3 documentation:
美国标准 - 在美国使用Amazon S3服务器
这是默认区域。 自动显示美国标准区域 将请求路由到北弗吉尼亚州或太平洋地区的设施 西北航空使用网络地图。要使用此区域,请选择美国标准 作为在控制台中创建存储桶时的区域。美国标准 Region为所有请求提供最终一致性。 [强调我的]
此隐式CDN行为对于此默认区域的S3(即美国标准)是唯一的,而在我认为的任何其他AWS服务上的其他地方都看不到。
我有一个微弱的S3内存实际上将零字节对象/密钥放入更近期区域的模拟目录/文件夹的存储桶中(即除了美国标准之外),而传统的解决方案对于美国标准区域可能会有所不同,例如,仅仅基于已建立的/
目录分隔的命名约定,并且完全省略了专用对象/密钥。
如果分析是正确的,除了为两种情况维护单独的代码路径之外,你无能为力,我担心
祝你好运!答案 2 :(得分: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)
答案 3 :(得分:0)
我正在使用“文件夹”没有“。”的事实。在它的道路上。 一个文件。 媒体/图像不会被删除 media / images / sample.jpg将被删除
e.g。清理存储桶文件
def delete_all_bucket_files(self,bucket_name):
bucket = self.get_bucket(bucket_name)
if bucket:
for key in bucket.list():
#delete only the files, not the folders
if period_char in key.name:
print 'deleting: ' + key.name
key.delete()
答案 4 :(得分:0)
您可以使用 size 参数来排除前缀:
for key in keys:
if key.size > 0:
print key