programing

Rails 마이그레이션-유형 변환이있는 change_column

copysource 2021. 1. 16. 20:41
반응형

Rails 마이그레이션-유형 변환이있는 change_column


나는 이미 Google에서 약간의 검색을 수행했으며 내 문제에 대한 만족스러운 답변이없는 것 같습니다.

문자열 유형의 열이있는 테이블이 있습니다. 다음 마이그레이션을 실행하고 싶습니다.

class ChangeColumnToBoolean < ActiveRecord::Migration
    def up
        change_column :users, :smoking, :boolean
    end
end

이것을 실행하면 다음과 같은 오류가 발생합니다.

PG::Error: ERROR:  column "smoking" cannot be cast automatically to type boolean
HINT:  Specify a USING expression to perform the conversion.
: ALTER TABLE "users" ALTER COLUMN "smoking" TYPE boolean

순수 SQL을 사용하여이 마이그레이션을 수행 할 수 있다는 것을 알고 있지만 Rails로 수행 할 수 있다면 더 좋을 것입니다. Rails 코드를 살펴 봤는데 그런 가능성이없는 것 같지만 누군가가 방법을 알고 있습니까?

나는 관심이 없다 :-순수 SQL-열 삭제-다른 열 생성, 데이터 변환, 원본 삭제 및 이름 변경


smoking열의 문자열 이 이미 유효한 부울 값인 경우 다음 문은 데이터 손실없이 열 유형을 변경합니다.

change_column :users, :smoking, 'boolean USING CAST(smoking AS boolean)'

마찬가지로이 문을 사용하여 열을 정수로 캐스트 할 수 있습니다.

change_column :table_name, :column_name, 'integer USING CAST(column_name AS integer)'

Postgres를 사용하고 있습니다. 이 솔루션이 다른 데이터베이스에서 작동하는지 확실하지 않습니다.


모든 데이터베이스가 열 유형을 변경할 수있는 것은 아닙니다. 일반적으로 사용되는 접근 방식은 원하는 유형의 새 열을 추가하고, 데이터를 가져오고, 이전 열을 제거하고, 새 열의 이름을 바꾸는 것입니다.

add_column :users, :smoking_tmp, :boolean

User.reset_column_information # make the new column available to model methods
User.all.each do |user|
  user.smoking_tmp = user.smoking == 1 ? true : false # If smoking was an int, for example
  user.save
end

# OR as an update all call, set a default of false on the new column then update all to true if appropriate.
User.where(:smoking => 1).update_all(:smoking_tmp = true) 

remove_column :users, :smoking
rename_column :users, :smoking_tmp, :smoking

postgres의 부울에 적합합니다.

change_column :table_name, :field,'boolean USING (CASE field WHEN \'your any string as true\' THEN \'t\'::boolean ELSE \'f\'::boolean END)'

당신은 좀 더 추가 할 수 있습니다 WHEN- THEN당신의 표현에 조건을

다른 데이터베이스 서버의 경우 데이터베이스 서버의 구문을 기반으로 표현식이 구성되지만 원칙은 동일합니다. 안타깝게도 SQL 없이는 수동 변환 알고리즘만으로 충분하지 않습니다.

구문 change_column :table, :filed, 'boolean USING CAST(field AS boolean)'이있는 방법 은 필드의 내용이 다음과 같은 경우에만 적합합니다. true / false / null


Postgres를 사용하고 있기 때문에 지금은 SQL 솔루션을 사용했습니다. 사용 된 쿼리 :

    execute 'ALTER TABLE "users" ALTER COLUMN "smoking" TYPE boolean USING CASE WHEN "flatshare"=\'true\' THEN \'t\'::boolean ELSE \'f\'::boolean END'

true / false 문자열로 채워진 필드가있는 경우에만 작동합니다 (예 : 강제 부울 유형의 기본 라디오 버튼 컬렉션 도우미가 생성됨).

참조 URL : https://stackoverflow.com/questions/17075173/rails-migrations-change-column-with-type-conversion

반응형