在Rails中动态创建mysql列

时间:2017-08-01 22:13:08

标签: mysql ruby-on-rails ruby

我正在开发一个私有api,它将我们的dbs / vendor数据统一在一个sql db中。

我们的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);

1 个答案:

答案 0 :(得分: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