错误 "未初始化的常量 AWS (NameError)"

42

这段话的意思是AWS未初始化,使用了aws-sdk-core gem。我尝试使用aws-sdk gem,但问题仍然存在。这是初始文件initializers/aws.rb:

AWS.config(:access_key_id => ENV['AWS_ACCESS_KEY_ID'],
                      :secret_access_key => ENV['AWS_SECRET_ACCESS_KEY'])

s3 = AWS::S3.new
AVATAR_BUCKET = s3.buckets[ENV['AVATAR_BUCKET_NAME']]

当我尝试运行服务器或打开控制台时,我会遇到这个错误:

/initializers/aws.rb:1:in `': uninitialized constant AWS (NameError)


/initializers/aws.rb:1:in `': uninitialized constant AWS (NameError)

7个回答

114
如果您收到此错误并已安装“aws-sdk”宝石包,则可能意外升级到了宝石包版本2。版本2使用“Aws”命名空间,而不是“AWS”。这使得应用程序可以同时使用版本1和版本2。
更多信息请参见博客文章

1
如果您计划继续使用SDK的版本一,请按照v1文档中的说明执行以下操作:gem install aws-sdk-v1require aws-adk-v1 - SJP
2
这个答案很可能是针对当前遇到此问题的人的正确答案。我回答的原始问题早于aws-sdk版本2。 - Chris Aitchison

24

你需要安装/使用-v1版本的aws-sdk。仅仅执行gem 'aws-sdk'或者require 'aws-sdk'可能会使用2.x版本的aws-sdk

为避免混淆,对于需要1.x版本的脚本,请使用:

require 'aws-sdk-v1' # not 'aws-sdk'

对于需要2.x的脚本,请使用:

gem 'aws-sdk', '~> 2'

根据GitHub文档所示。


即使我没有直接使用它(在我的情况下,正确的 gem 版本就足够了,不需要添加 require 行),这个答案还是很有帮助的。这是一个提醒我们要谨慎更新 gems 的好方法。 - maurice

17

你可能会遇到这个错误,因为在你的Gemfile中没有定义正确的aws sdk版本。这可能会在重新绑定已安装版本1或2的旧应用程序时发生。

确保你想要安装的版本:

aws-sdk版本3

gem 'aws-sdk', '~> 3'

# call sdk    
Aws.<whatever>

aws-sdk 2 版本

gem 'aws-sdk', '~> 2'

# call sdk    
Aws.<whatever>

aws-sdk 1 版本

# version constraint
gem 'aws-sdk', '< 2'

# or 

# use the v1 gem
gem 'aws-sdk-v1'

# call sdk    
AWS.<whatever>

v1 作用域在 AWS 下,而 v2 和 v3 的作用域在 Aws 下 => 这允许您同时运行 v1 和 v2。


7
似乎你的加载路径中没有安装这个 gem 或者没有被引用。
在你的 Gemfile 中应该添加以下内容:
gem 'aws-sdk'

这样做会在应用程序初始化时隐式地执行`require 'aws-sdk'`,只要你使用bundle exec rails serverbundle exec rails console启动应用程序即可。
另外,如果上述代码在非 Rails 应用中,则将`require 'aws-sdk'`放置在第一行即可。

非常感谢!为什么在第一行添加require'aws-sdk'似乎解决了它?!?= c ...这是Rails的问题! - bezzoon
1
这不是解决方法。如果您同时安装了aws-sdk的1.x和2.x版本,则此行代码不一定会加载正确的版本。 - DrStrangepork
1
你说得对,尽管 OP 在版本 2 存在之前就提出了这个问题。 - Chris Aitchison
1
@cmaitchison,能否告诉我gemfile的位置在哪里?我知道所有的gems都在哪里,但从你的回答中看来,gemfile是一些配置或初始化文件。谢谢。 - shaffooo
2
如果你的项目根目录中没有Gemfile文件,那么Trevor Rowe的回答可能更相关于你的问题。当你使用Ruby依赖管理工具Bundler时,一个名为Gemfile的文件是必需的。 - Chris Aitchison
显示剩余3条评论

4
我在Chef配方中遇到了这个问题,因此下面的响应明显是面向Chef的。
亚马逊在2015年2月初发布了aws-sdk的第2版。 第2版与第1版不完全兼容。
因此,您必须做出决定-您是否满意第1版功能,还是想要第2版功能?
如果您对第1版感到满意,或许短期内,有必要让Chef显式加载第1版,因为默认情况下,它似乎使用最新版本。 为此,您必须在加载chef_gem aws-sdk的配方中指定要加载的版本属性。 修改如下(可能在特定食谱的default.rb中实现):
chef_gem "aws-sdk" do
  action :nothing

  # Source:  https://aws.amazon.com/releasenotes/Ruby?browse=1
  version '1.62.0'  

end.run_action(:install)

更新食谱元数据中的版本,然后将食谱上传到您的Chef服务器。更新环境中的食谱版本,然后将环境上传到您的Chef服务器。

收敛后,在实例上运行gem列表以查看gem版本:

在PowerShell上 PS C:\Users\Administrator> gem list | select-string aws-sdk

在Linux上: gem list | grep -i aws-sdk

这些是典型的结果:

aws-sdk (2.0.27, 1.62.0) 
aws-sdk-core (2.0.27) 
aws-sdk-resources (2.0.27) 
aws-sdk-v1 (1.62.0)

注意最后一个指定的是 aws-sdk-v1。现在,您必须更新配方以要求旧版本的 aws-sdk。将此更改为:
require 'aws-sdk'

转换为:

require 'aws-sdk-v1'

更新metadata.rb中的版本号,上传cookbook,更新环境文件中的版本号,上传环境,在下次收敛后即可解决问题。

此博客文章包含更多详细信息和解决方案: http://ruby.awsblog.com/post/TxFKSK2QJE6RPZ/Upcoming-Stable-Release-of-AWS-SDK-for-Ruby-Version-2


2
我曾面临相同的问题。在不更新 gem 的情况下,有一个答案可以解决问题。
只需根据需要更改 [environment 中 require 语句中的位置] 即可。
require 'aws-sdk'

to

require 'aws-sdk-v1'

谢谢,伙计,爱你。 - Thomas

1
我并不是一名Ruby专家,但我通过运行以下命令解决了相同的问题。
要删除已安装的AWS gem,请执行以下操作。
gem list --no-version --local | grep aws | xargs gem uninstall -aIx

安装与我的Ruby脚本兼容的v1 gem:

gem install aws-sdk -v 1.64.0

我同意这不是AWS推荐的方式,因为AWS建议使用最新版本,但对于那些不想修改现有脚本的人来说,这应该是有用的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接