2017-08-01 111 views
0

我正在研究一個將我們的許多數據庫/供應商數據統一在一個sql數據庫中的私有API。在Rails中動態創建mysql列表

我們的ESP面臨着挑戰,我們的營銷人員總是在更換/添加新的色譜柱。我們希望此應用能夠隨着這些列更改進行擴展,並且不需要每次更改名稱或添加新屬性時都按摩列。我需要使用Rails實時創建列的列表(我們不希望在Mysql中完成這100%,因爲我們正在重命名映射中的某些列)。

table = "customer" 
attrs = ["vendor_cm_name_d", "vendor_cm_email address_d", "vendor_cm_date added_d", "vendor_cm_extid_d" ] 

attrs.each_with_index do |attr, i| 
    connection = ActiveRecord::Base.connection 
    connection.execute("ALTER TABLE #{table} ADD COLUMN #{attr} VARCHAR(15);" ) 
    # this didnt work :-(connection.close 
end 

該方法只能工作在一列,但在數組中有多個元素時失敗。閱讀日誌(粘貼在下面)看起來好像試圖將整個語句作爲一個調用運行,而不是以事務方式運行。我試圖在每個循環結束之前添加一個connection.close,但這也不起作用。所有的指針都是受歡迎的。

Mysql2::Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'address_d VARCHAR(15)' at line 1: ALTER TABLE customer ADD COLUMN vendor_cm_email address_d VARCHAR(15); 
ActiveRecord::StatementInvalid: Mysql2::Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'address_d VARCHAR(15)' at line 1: ALTER TABLE customer ADD COLUMN vendor_cm_email address_d VARCHAR(15); 
+0

這可能是一個超級壞主意。爲什麼不轉向無模式設計? MySQL 5.7支持JSON列,這對於這類事情來說非常棒,儘管它的缺點是它們不易被索引或操縱。 Postgres爲JSON提供了極好的支持,您可以將它編入索引並輕鬆操作,這可能值得考慮作爲選項。還有更多純粹的文檔商店,比如MongoDB,它們全面採用這個概念。 – tadman

+0

另一種更純粹的RDBMS方法是爲行數據創建鍵/值表對。這可能會變得非常混亂,並經常被視爲反模式,但它可以讓你擺脫這樣的困境,你真的不知道你需要容納哪些數據。改變大型桌子可能會使服務器癱瘓,並可能導致嚴重的服務中斷。這是你不願意做的事情,而不是設計。 – tadman

+0

@tadman是的,我同意。我絕不會在其他任何地方爲此做數據倉庫的私人API。 – jahrichie

回答

1

您的sql不起作用,因爲列名具有空格。將生成的sql中的列名換成引號。

attrs.each_with_index do |x, i| 
    connection = ActiveRecord::Base.connection 
    connection.execute "ALTER TABLE #{table} ADD COLUMN \"#{x}\" VARCHAR(15);" 
# this didnt work :-(connection.close 
end 

雖然我寧願不走自己編寫sql的路徑。相反,你可以這樣創建一個服務:

class DbService < ActiveRecord::Migration 
    def initialize(table_name) 
    @table_name = table_name 
    end 
    def add_string_column(column_name) 
    add_column @table_name, column_name, :string 
    end 
end 

然後像做

service = DbService.new("customer") 
attrs.each do |column_name| 
    service.add_string_column(column_name) 
end 
+0

我不能相信我錯過了。我使用了rails helper來替換帶下劃線的空格,這顯然有問題。解決。非常感謝!! – jahrichie