是否可以在sqlite数据库中具有相同的索引名称?

时间:2015-09-14 18:31:19

标签: mysql ruby-on-rails database sqlite schema.rb

我有一个Ruby on Rails应用程序,开发数据库在Mysql中。我决定使用sqlite数据库进行测试。为此,我做了以下事情:

  1. 配置 database.yml 文件以支持test.sqlite3以测试环境

  2. 使用rake db:schema:dump

  3. 转储当前开发数据库架构
  4. 使用schema.rb尝试使用该命令在test.sqlite3数据库文件中生成表。 rake db:test:clone
  5. 然后它开始繁荣。我得到了一个例外

    SQLite3::SQLException index XXX
    already exists:CREATE INDEX "XXX" ON table ("XXX")
    

    当我仔细调查迁移文件和架构时,我意识到在多个表中使用了相同的索引名称。例如,schema.rb中的一些语句是这样的:

    add_index("patients", ["appointment_id"], {:name=>"appointment_id"})
    add_index("doctors", ["appointment_id"], {:name=>"appointment_id"})
    

    我知道mysql在表的范围内维护索引名的唯一性。现在一个简单的解决方案可能是恢复到测试数据库的 mysql 。我无法弄清楚在这种特殊情况下是否有可能从schema.rb生成一个sqlite文件。

    现在出现了奇怪的部分。我做了以下更改并在虚拟应用程序中进行了测试。

    add_index("patients", ["appointment_id"], {:name=>"pappointment_id"})
    add_index("doctors", ["appointment_id"], {:name=>"dappointment_id"})
    

    有效!现在我可能想在我的真实应用程序中做同样的事情。严酷的现实是,我需要在很多地方进行重命名和生产,这将不仅仅是一项繁琐的工作,因为如果删除旧索引并添加新索引,我们会有数百万条记录受到影响(Mysql 5.5) 。有出路吗?

1 个答案:

答案 0 :(得分:0)

您正在尝试添加测试数据库中已存在的索引。因此,在您的测试数据库的患者表上已经存在了appointment_id的索引。您可以尝试RAILS_ENV = test rake db:drop db:create db:test:clone它应该运行正常。这就是说我喜欢为我的迁移添加条件以避免问题。例如:

add_column :patients, :appointment_id, :integer unless column_exists? :patients, :appointment_id

请为所有神圣之爱的爱不要将你的prod专栏重命名为pappointment_id或任何类似的东西。