将外部数据库连接到 Rails 4 应用程序时出错

Posted

技术标签:

【中文标题】将外部数据库连接到 Rails 4 应用程序时出错【英文标题】:Error connecting external DB to Rails 4 App 【发布时间】:2014-04-11 15:17:38 【问题描述】:

我正在尝试将 Postgresql Redshift 数据库添加到我的 Rails 4 应用程序中,以便在本地和生产中使用。我首先在开发中进行测试。

我已将我的 database.yml 文件更改为如下所示:

development:
  adapter: postgresql
  encoding: unicode
  database: new_db
  pool: 5
  username: test
  password: password
  host: test_db.us-east-1.redshift.amazonaws.com
  port: 5439

现在,当我点击localhost:3000 时,我得到了这个错误:

将参数“client_min_messages”设置为“警告”的权限被拒绝 : 将 client_min_messages 设置为“警告”

我似乎无法找出导致此问题的原因 - 似乎我的新数据库可能不允许 SET 命令?我不太确定,但感谢您提供任何帮助。

【问题讨论】:

【参考方案1】:

刚刚在其他地方回答了这个问题,但我今天遇到了同样的问题,这就是我所做的,它现在正在工作:

#app/models/data_warehouse.rb
class DataWarehouse < ActiveRecord::Base                      
  establish_connection "redshift_staging"
  #or, if you want to have a db per environment
  #establish_connection "redshift_#Rails.env"
end

请注意,我们连接的是 5439,而不是默认的 5432,所以我指定了端口 另外,我指定了一个模式 beta,这是我们用于不稳定聚合的模式,您可以如上所述为每个环境使用不同的数据库,或者使用各种模式并将它们包含在 ActiveRecord 的搜索路径中

#config/database.yml
redshift_staging:                                                          
  adapter: postgresql                                                      
  encoding: utf8                                                           
  database: db03                                                         
  port: 5439                                                               
  pool: 5                                                                  
  schema_search_path: 'beta'                                                                                          
  username: admin                                                        
  password: supersecretpassword                                               
  host: db03.myremotehost.us  #your remote host here, might be an aws url from Redshift admin console 

###OPTION 2,直接PG连接

  class DataWarehouse < ActiveRecord::Base                      

    attr_accessor :conn                                                       

    def initialize                                                            
      @conn = PG.connect(                                                     
       database: 'db03',                                                   
       port: 5439,                                                           
       pool: 5,                                                              
       schema_search_path: 'beta',                                           
       username: 'admin',                                                  
       password: 'supersecretpassword',                                         
       host: 'db03.myremotehost.us'                                               
      )                                                                       
    end    
  end


[DEV] main:0> redshift = DataWarehouse
E, [2014-07-17T11:09:17.758957 #44535] ERROR -- : PG::InsufficientPrivilege: ERROR:  permission denied to set parameter "client_min_messages" to "notice" : SET client_min_messages TO 'notice'
(pry) output error: #<ActiveRecord::StatementInvalid: PG::InsufficientPrivilege: ERROR:  permission denied to set parameter "client_min_messages" to "notice" : SET client_min_messages TO 'notice'>   

更新:

我最终选择了选项 1,但现在出于多种原因使用此适配器:

https://github.com/fiksu/activerecord-redshift-adapter

原因 1:ActiveRecord postgresql 适配器设置 client_min_messages 原因 2:适配器还尝试设置时区,这是 redshift 不允许的 (http://docs.aws.amazon.com/redshift/latest/dg/c_redshift-and-postgres-sql.html) 原因 3:即使您为前两个错误更改 ActiveRecord 中的代码,您也会遇到其他错误,抱怨 Redshift 正在使用 Postgresql 8.0,此时我转向适配器,如果我发现更好的东西,我会重新访问和更新稍后。

我将我的表重命名为 base_aggregate_redshift_tests(注意复数),以便 ActiveRecord 可以轻松连接,如果您无法在 redshift 中更改表名,请使用我在下面注释掉的 set_table 方法

#Gemfile:
gem 'activerecord4-redshift-adapter', github: 'aamine/activerecord4-redshift-adapter'

选项 1

#config/database.yml
redshift_staging:                                                                                                             
  adapter: redshift                                                                                                           
  encoding: utf8                                                                                                              
  database: db03                                                                                                           
  port: 5439                                                                                                                  
  pool: 5                                                                                                                     
  username: admin                                                                                                
  password: supersecretpassword                                                                                                  
  host: db03.myremotehost.us                                                                                                       
  timeout: 5000   

#app/models/base_aggregates_redshift_test.rb
#Model named to match my tables in Redshift, if you want you can set_table like I have commented out below

class BaseAggregatesRedshiftTest < ActiveRecord::Base
  establish_connection "redshift_staging"
  self.table_name = "beta.base_aggregates_v2"
end

在控制台中使用 self.table_name -- 注意它会查询正确的表,因此您可以随意命名模型

[DEV] main:0> redshift = BaseAggregatesRedshiftTest.first                                                                    
D, [2014-07-17T15:31:58.678103 #43776] DEBUG -- :   BaseAggregatesRedshiftTest Load (45.6ms)  SELECT "beta"."base_aggregates_v2".* FROM "beta"."base_aggregates_v2" LIMIT 1            

选项 2

#app/models/base_aggregates_redshift_test.rb
class BaseAggregatesRedshiftTest < ActiveRecord::Base
  set_table "beta.base_aggregates_v2"

  ActiveRecord::Base.establish_connection(
    adapter: 'redshift',
    encoding: 'utf8',
    database: 'staging',
    port: '5439',
    pool: '5',
    username: 'admin',
    password: 'supersecretpassword',
    search_schema: 'beta',
    host: 'db03.myremotehost.us',
    timeout: '5000'
  )

end

#in console, abbreviated example of first record, now it's using the new name for my redshift table, just assuming I've got the record at base_aggregates_redshift_tests because I didn't set the table_name

[DEV] main:0> redshift = BaseAggregatesRedshiftTest.first
D, [2014-07-17T15:09:39.388918 #11537] DEBUG -- :   BaseAggregatesRedshiftTest Load (45.3ms)  SELECT "base_aggregates_redshift_tests".* FROM "base_aggregates_redshift_tests" LIMIT 1
#<BaseAggregatesRedshiftTest:0x007fd8c4a12580> 
                                                :truncated_month => Thu, 31 Jan 2013 19:00:00 EST -05:00,
                                                :dma => "Cityville",
                                                :group_id => 9712338,
                                                :dma_id => 9999 
                                                

祝你好运!

【讨论】:

【参考方案2】:

你的 postgresql 版本是什么?还是中间件版本?不是postgresql原版?

您可以使用 \set VERBOSITY 详细 然后再做一次,找到哪个 function@code 引发错误。 然后分析一下为什么不能设置client_min_messages。

我使用 postgresql 9.3.3 没有这个问题。 超级用户和普通用户可以正确设置client_min_messages。

digoal=# \c digoal digoal
You are now connected to database "digoal" as user "digoal".
digoal=> set client_min_messages=debug;
SET
digoal=> set client_min_messages=warning;
SET
digoal=> SET client_min_messages TO 'warning';
SET
digoal=> \c postgres digoal
You are now connected to database "postgres" as user "digoal".
postgres=> SET client_min_messages TO 'warning';
SET

【讨论】:

【参考方案3】:

我能够通过为 Activerecord 打开 postgresql 适配器并注释掉所有 SET 命令来解决这个问题。

但是,这根本不是最佳做法。在编辑 postgresql 适配器结束时,由于 postgres 版本过时 (80002),我遇到了错误。

正确的答案是更新 postgres,不幸的是,这在我位于 Amazon 的共享 Redshift DB 中是不可能的。

【讨论】:

或者您可以修改您的postgresql版本的代码,并注释掉这些错误代码部分,忽略这些错误。然后重新编译它。

以上是关于将外部数据库连接到 Rails 4 应用程序时出错的主要内容,如果未能解决你的问题,请参考以下文章

Rails 4部署后无法连接到mysql

Rails 4.1.4 在推送到 Heroku 时尝试连接到未初始化的 Mongo 数据库(rake assets:precompile)

(在localhost上连接到Redis时出错:6379(Errno :: ECONNREFUSED)):

使用java将oracle数据库连接到apache spark时出错

将 Rails 连接到 AWS MySQL 数据库

将 nesjs 应用程序连接到 SQL Server Express 时出错:无法连接到 localhost:1433 - 自签名证书