Faça apenas uma migração


94

Estou tentando executar apenas uma migração de um monte em meu aplicativo Rails. Como posso fazer isso? Não quero fazer nenhuma migração antes ou depois. Obrigado.


1
Este seria um recurso conveniente do rails: adicione um STEP=nargumento para db:migrate(onde né o número de migrações a serem executadas, assim como existe db:rollback) - então você poderia fazer rake db:migrate STEP=1ou rake db:migrate STEP=2, etc.
user664833

Respostas:


164

rake db:migrate:redo VERSION=xxxxxxx, mas isso executará o downe, em seguida, a upetapa. Você pode fazer isso em conjunto com a observação da etapa de descida temporariamente.


Hmm, blog.stonean.com/2007/12/18/rake-dbmigrateredo , :: redo não parece aceitar um argumento VERSION.
Terry G Lorber

3
@pedrorolo: Não está desatualizado. Esta tarefa não tem descrição e, portanto, não aparecerá em rake -T.
Ryan Bigg,

1
@pedrorolo: db:test:preparetambém não aparece nessa lista. Deus, estou atrasado para a festa.
maroncruz

9
Para expandir o que Ryan diz, se a tabela foi descartada do banco de dados fora do Rails, rake db:migrate:up VERSION=my_versionpode não fazer nada , porque a tabela schema_migrations ainda diz que foi executada. Na mesma situação rake db:migrate:redo VERSION=my_versionpode falhar porque não pode largar a mesa. Neste caso, comente o downmétodo na migração temporariamente e execute novamenterake db:migrate:redo...
Leo,

3
E para expandir o que @Leo diz, se a migração for definida com alteração de def, altere para def self.up além do acima.
valk

70
rake db:migrate:up VERSION=1234567890

da mesma forma rake db:migrate:downpara eliminar uma migração específica. Você pode obter uma lista de tarefas de rake disponíveis com rake -T.


4
O VERSIONmencionado aqui é o valor inteiro no início de cada um de seus arquivos de migração (que é apenas o carimbo de data / hora de quando foi criado). Por exemplo VERSION=20150720023630,.
codificação aaron de

3
As versões são bem exibidas com rake db: migrate: status
jpgeek

Digno de nota, VERSIONé apenas uma variável de ambiente para que possa vir primeiro no comando ou mesmo configurada antes do comando:VERSION=1234567890 rake db:migrate:up
Joshua Pinter

25

Tive que executar uma única migração que mudou e precisava ser executada novamente, independentemente de todas as outras migrações. Abra o console e faça o seguinte:

>> require 'db/migrate/your_migrations.rb'
=> ["YourMigrations"]
>> YourMigrations.up
=> etc... as the migration runs
>> YourMigration.down

Mais útil, isso poderia ser colocado em uma tarefa de rake etc.


6
Isso funcionou incrivelmente. Você também pode simplesmente copiar e colar o código da migração no console para definir a classe (e isso permite a manipulação manual se necessário, se você acabou de cometer um erro no Dev, por exemplo). Se você definiu uma migração reversível com change, execute em seu YourMigrations.migrate(:up)lugar (ou :downtambém!)
trisweb

1
você pode ter querequire "#{Rails.root}/db/migrate/your_migrations.rb"
s2t2

15

rake db:migrate:up VERSION=version_no

Irá migrar (adicionar) um script de migração específico

rake db:migrate:down VERSION=version_no

Irá deletar script de migração específico


10
rake db:migrate VERSION=20098252345

tente.


7
Acho que isso irá executar qualquer migração até aquele que você especificou.
Ken Liu

1
fechar, mas que também executa quaisquer migrações antes da migração específica.
Anon

6
Não acho que você deva / queira executar apenas uma migração sem considerar as anteriores. Uma migração é uma representação da estrutura do banco de dados em relação ao código em um determinado ponto no tempo e, portanto, as migrações anteriores são necessárias. Se você deseja executar apenas uma migração, é provável que você não tenha escrito as operações up / down adequadas para manter as migrações funcionais ... é um mau hábito escrever apenas as suas migrações.
JP Silvashy

1
Digno de nota: VERSIONé apenas uma variável de ambiente para que possa vir primeiro no comando ou mesmo configurada antes do comando:VERSION=20098252345 rake db:migrate
Joshua Pinter

4
rake db:migrate:redo version='xxxx'   

Lembre-se de colocar aspas em torno de xxxx, xxxx é o carimbo de data / hora (ou ID de migração) para sua migração.

Você pode verificar os carimbos de data / hora (ID de migração) para as migrações anteriores feitas usando

rake db:migrate:status    

3

Expandir a resposta por korch acima requirenão funcionou para mim, mas loadfuncionou. Para ser concreto, para o arquivo de migração:

    class ChangeMinQuantityToRaces < ActiveRecord::Migration
      def change
        change_column :races, :min_quantity, :integer, :default => 0
      end
    end

no console digitando

    > load 'db/migrate/30130925110821_change_min_quantity_to_races.rb'
    > ChangeMinQuantityToRaces.new.change

trabalhou para mim.

    > Race.new.min_quantity # => 0 

Isso foi para ruby ​​1.9.3p484 (2013-11-22 revisão 43786) [x86_64-linux] e Rails 3.2.13.


2

Adicionando meus 2 centavos a isso porque tive o mesmo problema:

Se você realmente deseja executar uma migração novamente sem criar uma nova, você pode fazer o seguinte:

rails dbconsole -p devdb=# delete from public.schema_migrations where version = '20150105181157';

E o rails "esquecerá" que executou a migração para 20150105181157. Agora, quando você executar db: migrate, ele executará novamente.

Isso quase sempre é uma má ideia. A única instância em que pode fazer sentido é se você tiver um branch de desenvolvimento e ainda não tiver desenvolvido sua migração e quiser adicionar algumas coisas a ela no desenvolvimento. Mas, mesmo assim, é melhor fazer sua migração bidirecional para que você possa reverter corretamente e tentar repetidamente.


1

Deve haver uma maneira de executar a classe de migração por meio do console. Não consigo fazer com que o código de migração seja reconhecível.

No entanto, como os comentários indicam, é preferível executar as migrações em ordem. Usar:

rake db:migrate VERSION=##########

Copie e cole seu código na migração para script / console?



0

Eu uso essa técnica no desenvolvimento quando mudo uma quantidade significativa de migração, e não quero migrar uma tonelada e perder nenhum dado ao longo do caminho (especialmente quando estou importando dados legados que levam muito tempo que Não quero ter que reimportar novamente).

Isso é 100% hackeado e eu definitivamente não recomendaria fazer isso na produção, mas funcionará:

  1. Mova a migração que deseja executar novamente de seu diretório para um local temporário
  2. Gere outra migração com o mesmo nome
  3. Copie / cole o código de migração original no arquivo de migração recém-gerado
  4. Execute a nova migração
  5. Exclua o arquivo de migração recém-gerado
  6. Edite suas migrações de esquema para remover o valor mais recente
  7. Restaurar o arquivo de migração antigo
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.