Como eu resolvo "o índice unique_schema_migrations já existe" no Rails?

A execução do rake db: migrate seguido do rake test: units produz o seguinte:

rake test:functionals
(in /projects/my_project)
rake aborted!
SQLite3::SQLException: index unique_schema_migrations already exists: CREATE UNIQUE INDEX "unique_schema_migrations" ON "ts_schema_migrations" ("version")

A parte relevante do db/schema.rb é a seguinte:

create_table "ts_schema_migrations", :id => false, :force => true do |t|
  t.string "version", :null => false
end

add_index "ts_schema_migrations", ["version"], :name => "unique_schema_migrations", :unique => true

Eu não estou alterando manualmente este índice em qualquer lugar, e estou usando o adaptador SQLite3 padrão do Rails com um novo banco de dados. (Isto é, executar o rm db/* sqlite3 antes do rake db: migrate não ajuda.)

A tarefa test: units talvez esteja tentando recarregar o esquema? Se sim, porque? Não deveria reconhecer que o esquema já está atualizado?

4
Definitivamente não há outras declarações de índice para a tabela schema_migrations no schema.rb. O bug não acontece no MySQL, curiosamente, no entanto.
adicionado o autor James A. Rosen, fonte
Também pode ter algo a ver com o meu usando table_name_prefix. Ao fazer um rake db: schema: load, recebo tabelas duplamente prefixadas.
adicionado o autor James A. Rosen, fonte

3 Respostas

No SQLite, a exclusividade do nome do índice é aplicada no nível do banco de dados. No MySQL, a exclusividade é aplicada apenas no nível da tabela. É por isso que suas migrações funcionam no segundo e não no primeiro: você tem dois índices com o mesmo nome em tabelas diferentes.

Renomeie o índice ou localize e renomeie o outro índice unique_schema_migrations e suas migrações devem funcionar.

14
adicionado
Eu tive o mesmo problema no Laravel, quando os testes começaram a migrar, o índice já existe. Eu mudei todos os índices para ter um nome único (prefixando o nome da tabela) e funcionou. Esta é a resposta correta, acredito.
adicionado o autor morksinaanab, fonte

Em seu arquivo database.yml, seus ambientes estão configurados para se conectar a diferentes bancos de dados para Desenvolvimento e Teste?

IE:

development:
  adapter: sqlite3
  database: db/dev.sqlite3
  timeout: 5000

test:
  adapter: sqlite3
  database: db/test.sqlite3
  timeout: 5000
2
adicionado

Try to search if your schema.rb file does not contain other declarations that create an index with the same name: unique_schema_migrations

0
adicionado