Вопрос по postgresql, ruby-on-rails-3, migration, ruby-on-rails – Как мне изменить строковый столбец в bigint?

6

В рельсах миграция. Как изменить столбец строкового типа на bigint?

Я имею:

<code>t.change :ip_number_from, :integer, :limit => 8
</code>

Я получил:

<code>PG::Error: ERROR:  column "ip_number_from" cannot be cast to type bigint
</code>

Я даже попробовал с 2 альтернативами:

<code>change_column :ip_to_countries, :ip_number_from, :integer, :limit => 8
change_column :ip_to_countries, :ip_number_from, :bigint
</code>

Все та же ошибка.

Ваш Ответ

3   ответа
0

Я недавно прочитал - но не помню, где - что вы не можете "бросить" строку " столбцы для & quot; int & quot; столбцы, но вы можете сделать наоборот. Актерский состав от & quot; int & quot; на "строку" необратимая миграция

Я найду документ, в котором я это прочел, и отредактирую свое сообщение, когда найду его.

Если вы можете, проще всего сделать то, что предлагает Юре Триглав. (Он разместил свой ответ перед моим, но я предлагал то же самое;)).

[Править] Я нашел, где я прочитал это:Необратимая миграция туто.

Error: User Rate Limit Exceeded
13

Postgres сообщает вам, что в этом столбце есть существующие данные, которые он не знает, как преобразовать, поэтому ему необходим оператор ALTER, который предоставляет предложение USING для столбца, чтобы указать, как преобразовывать существующие значения.

К сожалению, для достижения этой цели вам потребуется раскрыть код, специфичный для базы данных, или использовать что-то похожее на решение, предлагаемое здесь:

http://webjazz.blogspot.co.uk/2010/03/how-to-alter-columns-in-postgresql.html

Изменить: Вот как вы можете сделать это непосредственно в SQL при переносе:

execute <<-SQL
  ALTER TABLE ip_to_countries
  ALTER COLUMN ip_number_from TYPE bigint USING ip_number_from::bigint
SQL
Error: User Rate Limit ExceededIpToCountry.connection.execute('alter table ip_to_countries alter ip_number_from type bigint using ip_number_from::bigint;') Christian Fazzini
3

Что находится в вашем столбце ip_number_from?

В любом случае я бы наверное:

  • create a new column of type bigint,
  • copy the data from ip_number_from to new_column manually through rails console or a rake task,
  • drop the original ip_number_from column
  • rename new_column to ip_number_from

Или вы можете перейти на SQL, как предложил mjtko, но я не уверен, что это будет легче.

Update

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

def up
  add_column :table, :new_column, :bigint
  Model.reset_column_information
  Model.all.each do |m|
    m.update_attribute :new_column, Model.bigint_from_ip_number_from(m)
  end
  drop_column :table, :ip_number_from
  rename_column :table, :new_column, :ip_number_from
end

Затем вы должны также добавить соответствующую миграцию вниз.

Вы всегда можете разделить это на несколько миграций и проверить ход / успех на ходу.

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded

Похожие вопросы