Почему rake выдает эту ошибку миграции Rails?

У меня есть две машины... машина для разработки и машина для производства. Когда я впервые перенес свое приложение rails на рабочий сервер, у меня не было проблем. Я просто импортировал schema.rb, запустив rake db:schema:load RAILS_ENV=production. Все было хорошо.

Итак, затем на моей машине для разработки я сделал еще несколько изменений и еще одну миграцию, а затем скопировал новое приложение на производственную машину. Затем я попытался обновить базу данных, запустив rake db:migrate RAILS_ENV=production. Я получаю следующую ошибку: «В базе данных уже есть объект с именем schema_migrations».

Я думаю про себя, я не шучу, Рейк... это ты создал! Я запустил трассировку на грабли, и кажется, что грабли думают, что они запускались впервые. Однако, проанализировав мою таблицу schema_migrations на моем компьютере для разработки и на моем рабочем компьютере, вы можете увидеть, что есть разница в одной миграции, а именно в той, которую я хочу перенести.

Я также пытался явно указать номер версии, но это тоже не работает.

Любые идеи о том, как я могу обновить свой рабочий сервер?

Обновление:

Позвольте мне начать с того, что я не могу просто «отбросить» базу данных. Это рабочий сервер с чуть более чем 100 тыс. записей. Что произойдет, если аналогичная проблема возникнет в будущем? Могу ли я просто удалять таблицу каждый раз, когда возникает проблема с базой данных? На этот раз это может сработать, но не похоже на практическое долгосрочное решение каждой проблемы с базой данных. Я сомневаюсь, что проблема, с которой я сталкиваюсь сейчас, уникальна для меня.

  1. Похоже, что таблица schema_info и таблица schema_migrations одинаковы. В моей настройке у меня есть только «schema_migrations». Как указывалось ранее, разница между таблицей schema_migrations на рабочем сервере и на машине разработки составляет всего одну запись. То есть запись, содержащая номер версии изменения, которое я хочу перенести.

  2. В книге «Просто Rails 2», которую я читал, говорится, что при первом переходе на рабочий сервер вместо запуска rake db:migrate нужно просто запустить rake:db:schema:load.

  3. Если это имеет значение, я использую Rails версии 2.1.


person JP Richardson    schedule 24.10.2008    source источник


Ответы (9)


Это предположение, я признаю: я думаю, что, поскольку вы впервые запустили db:schema:load вместо db:migrate в своей производственной среде, вы получили структуру своей базы данных, но не данные, которые переносятся в вашу таблицу schema_info. Так что теперь, когда вы запускаете миграцию в производственной среде, в schema_info нет данных, поэтому миграция считает, что она еще не запущена (потому что это не так).

Тем не менее... вы говорите, что посмотрели в таблицу "schema_migrations" и что есть разница в одну версию от dev до производства... Я не слышал об этой таблице, хотя я несколько месяцев позади на моей версии рельсов. Возможно, вы могли бы попробовать создать таблицу «schema_info» в производственной среде с одним столбцом «версия» и добавить строку с версией, которая, по вашему мнению, используется в вашей производственной среде.

person Brad    schedule 24.10.2008
comment
да, таблица schema_migrations - это ваш ключ, возможно, ее нет, или она не заполнена, или что-то еще на вашем рабочем сервере. - person Cameron Booth; 25.10.2008

Если вы получаете сообщение «В базе данных уже есть объект с именем schema_migrations». сообщение об ошибке, то я подозреваю, что вы используете MS SQLServer в качестве базы данных? (Поскольку это похоже на сообщение об ошибке MS SQL Server)

Если да, то какой адаптер базы данных ActiveRecord вы используете? (Какой у вас файл database.yml, какие драгоценные камни вы установили для доступа к базе данных MS SQL Server?)

В настоящее время кажется, что Rails не находит таблицу schema_migrations в производственной схеме и поэтому пытается создать ее, но это создание завершается ошибкой с сообщением об ошибке базы данных. Вероятно, причина в символах верхнего/нижнего регистра в имени таблицы schema_migrations - насколько я понимаю, идентификаторы MS SQL Server чувствительны к регистру.

person Raimonds Simanovskis    schedule 31.10.2008
comment
Да, я использую MS SQL Server. Моя производственная машина работает на Linux, я использую адаптер ruby ​​ODBC. Мой файл database.yml выглядит следующим образом: производство: адаптер: odbc dsn: YOUR_DB_DEFINITION_NAME имя пользователя: USERNAME пароль: PASSWORD Однако в «schema_migrations» имя таблицы написано в нижнем регистре. - person JP Richardson; 31.10.2008
comment
Пожалуйста, подключитесь к своей производственной среде с помощью скрипта/консоли и выполните ActiveRecord::Base.connection.tables.include?(ActiveRecord::Migrator.schema_migrations_table_name) Если это неверно, проверьте содержимое ...tables и ...schema_migrations_table_name - person Raimonds Simanovskis; 01.11.2008

В зависимости от системы, используемой в производстве, я видел случаи, когда приведенное ниже не работало:

rake db:migrate RAILS_ENV=production

Но где это работает:

RAILS_ENV=production rake db:migrate

Причудливо, я знаю, но стоит попробовать, чтобы увидеть, есть ли разница.

person Marc L    schedule 01.04.2009

Что касается вашего обновления:

  1. Я не понимаю, в чем разница между вашей рабочей версией schema_migrations и версией для разработчиков. Есть ли запись в обеих таблицах (должен быть только 1 столбец, «версия», правильно) или есть одна запись в базе данных разработчиков и ноль записей в производстве? Если в производственной таблице нет записей, то делаем так:

    ActiveRecord::Base.connection.execute("INSERT schema_migrations (version) VALUES(#{my version number that production is supposedly on})")

  2. В качестве альтернативы вы можете попробовать полностью удалить таблицу schema_migrations в рабочей среде:

    ActiveRecord::Base.connection.execute("DROP TABLE schema_migrations")

    Затем повторный запуск rake db:migrate RAILS_ENV=production. Это будет запускать миграции, начиная с версии 1, что, вероятно, не то, что вам нужно.

  3. В качестве альтернативы вы можете запустить сеанс IRB в своей производственной среде, выполнить либо «требование», либо «загрузку» (я никогда не могу вспомнить, что именно или если это имеет значение) файла миграции, который вы хотите загрузить, а затем вызвать MyMigrationClass.up . После этого вам нужно будет вручную установить номер версии в таблице schema_migrations, так как у вас все еще будет проблема в будущем, но в качестве быстрого исправления это сработает.

person Brad    schedule 28.10.2008

Я бы просто удалил БД, добавил ее снова и запустил rake rb:migrate. Брэд прав в том, что когда вы запустили загрузку схемы, она не поместила никаких записей в таблицу schema_migrations.

Конечно, это сложнее, если на рабочем сервере есть данные, которые вы не можете потерять. Вы можете получить задачи резервного копирования rake (не уверен, является ли это частью ядра или нет), а затем запустить rake db:backup:write в вашей производственной базе данных, а затем после того, как вы обновите миграции в рабочей среде, запустите rake db: резервная копия: читать.

person Kyle Boon    schedule 25.10.2008
comment
если бы это было правдой или лучшим путем, никакие изменения никогда не вносились бы в производственные системы, которые в реальной жизни почти всегда имеют данные, которые необходимо поддерживать :) - person Ian Terrell; 25.10.2008
comment
Я рекомендую это только потому, что он не выполнил миграцию должным образом в первый раз. - person Kyle Boon; 27.10.2008

schema_info из старой версии Rails. schema_migrations — новинка в этом блоке. Вы должны иметь возможность удалить таблицу schema_info, так как она больше не будет использоваться. Вы, вероятно, захотите найти любые проблемы, связанные с этим изменением имени.

person Community    schedule 11.11.2008

rake db:schema:load загрузит структуру базы данных из schema.rb. Этот файл является текущим представлением структуры базы данных. Он используется, когда у вас есть пустая схема (база данных), для которой необходимо создать все таблицы и индексы. Это избавляет вас от необходимости выполнять все миграции. Если у вас есть рабочая база данных с данными, вам не нужно ее запускать. Как говорили другие, это было бы плохо!

person Community    schedule 11.11.2008

Я знаю, что этот пост был некоторое время назад, но я наткнулся на него, и на него действительно не было ответа. Как это приходит на Google, вот идет.

Когда вы выполнили rake db:schema:dump (или когда это было сделано за вас скриптами сборки), он поместил определение таблицы миграции в schema.rb. В конце скрипта процесс снова попытается создать таблицу, однако очевидно, что она уже существует. Просто удалите таблицу миграции из schema.rb перед запуском rake:schema:load, и сообщения об ошибке не будет.

Вам нужно будет установить номер версии в таблице миграции для последующего запуска миграции. Поэтому важно знать, к какой версии относится ваш schema.rb, или удалить все старые миграции (они в безопасности в вашем SCM, верно?)

person wentbackward    schedule 21.10.2009

rake db:migrate RAILS_ENV=production

Используйте задачу db:schema:load только для первого создания, добавочные изменения должны быть перенесены.

person Ian Terrell    schedule 25.10.2008