There is no implicit (automatic) cast from text or varchar to integer (i.e. you cannot pass a varchar to a function expecting integer or assign a varchar field to an integer one), so you must specify an explicit cast using ALTER TABLE … ALTER COLUMN … TYPE … USING:
ALTER TABLE the_table ALTER COLUMN col_name TYPE integer USING (col_name::integer);
Note that you may have whitespace in your text fields; in that case, use:
ALTER TABLE the_table ALTER COLUMN col_name TYPE integer USING (trim(col_name)::integer);
to strip white space before converting.
This shoud’ve been obvious from an error message if the command was run in psql, but it’s possible PgAdmin-III isn’t showing you the full error. Here’s what happens if I test it in psql on PostgreSQL 9.2:
=> CREATE TABLE test( x varchar );
CREATE TABLE
=> insert into test(x) values ('14'), (' 42 ');
INSERT 0 2
=> ALTER TABLE test ALTER COLUMN x TYPE integer;
ERROR: column "x" cannot be cast automatically to type integer
HINT: Specify a USING expression to perform the conversion.
=> ALTER TABLE test ALTER COLUMN x TYPE integer USING (trim(x)::integer);
ALTER TABLE
Thanks @muistooshort for adding the USING link.
See also this related question; it’s about Rails migrations, but the underlying cause is the same and the answer applies.
If the error still occurs, then it may be related not to column values, but indexes over this column or column default values might fail typecast. Indexes need to be dropped before ALTER COLUMN and recreated after. Default values should be changed appropriately.
I’m trying to change gender column to integer in my rails app. It is said that when using postgresql, we have to write a little bit different way. i.e.
change_column :users, :gender, :integer, using: 'gender::integer'
or
change_column :users, :gender, 'integer USING CAST(gender AS integer)'
However, in my case, the aboves are still not working and got the below error.
PG::DatatypeMismatch: ERROR: default for column "gender" cannot be cast automatically to type integer
: ALTER TABLE "users" ALTER COLUMN "gender" TYPE integer USING gender::integer
Please tell me why it doesn’t work. Or some weird things I’ve got? For example typo.
My environment
- Ruby: 2.5.0
- Rails: 5.1.6
- Postgres: 11.1
asked Feb 17, 2019 at 12:34
![]()
Based on the error message you’re seeing, Postgres does not know how to keep the default value you’ve set while changing the database type to integer. I’d suggest:
- Dropping the default
- Changing the datatype on the column
- Adding the default in the new type
You may be able to do steps 2 and 3 in the same call. You’ll want to use something like the below in the up migration:
def up
execute "ALTER TABLE users ALTER gender DROP DEFAULT;"
change_column :users, :gender, :integer, using: 'gender::integer', default: 0
end
answered Feb 17, 2019 at 15:37
![]()
George SGeorge S
1,8669 silver badges12 bronze badges
3
I’m trying to change gender column to integer in my rails app. It is said that when using postgresql, we have to write a little bit different way. i.e.
change_column :users, :gender, :integer, using: 'gender::integer'
or
change_column :users, :gender, 'integer USING CAST(gender AS integer)'
However, in my case, the aboves are still not working and got the below error.
PG::DatatypeMismatch: ERROR: default for column "gender" cannot be cast automatically to type integer
: ALTER TABLE "users" ALTER COLUMN "gender" TYPE integer USING gender::integer
Please tell me why it doesn’t work. Or some weird things I’ve got? For example typo.
My environment
- Ruby: 2.5.0
- Rails: 5.1.6
- Postgres: 11.1
asked Feb 17, 2019 at 12:34
![]()
Based on the error message you’re seeing, Postgres does not know how to keep the default value you’ve set while changing the database type to integer. I’d suggest:
- Dropping the default
- Changing the datatype on the column
- Adding the default in the new type
You may be able to do steps 2 and 3 in the same call. You’ll want to use something like the below in the up migration:
def up
execute "ALTER TABLE users ALTER gender DROP DEFAULT;"
change_column :users, :gender, :integer, using: 'gender::integer', default: 0
end
answered Feb 17, 2019 at 15:37
![]()
George SGeorge S
1,8669 silver badges12 bronze badges
3
У меня есть небольшая таблица, и определенное поле содержит тип»разные символы«. Я пытаюсь изменить его на «целое » но это дает ошибку, что кастинг невозможен.
есть ли способ обойти это или я должен просто создать другую таблицу и принести в нее записи с помощью запроса.
поле содержит только целочисленные значения.
7 ответов
нет неявного (автоматического) приведения из text или varchar до integer (т. е. вы не можете пройти varchar к функции, ожидающей integer и назначить
этой работал для меня.
изменить столбец varchar на int
change_column :table_name, :column_name, :integer
есть:
PG::DatatypeMismatch: ERROR: column "column_name" cannot be cast automatically to type integer
HINT: Specify a USING expression to perform the conversion.
chnged to
change_column :table_name, :column_name, 'integer USING CAST(column_name AS integer)'
попробуйте это, это будет работать наверняка.
при написании миграции Rails для преобразования столбца строки в целое число вы обычно говорите:
change_column :table_name, :column_name, :integer
однако PostgreSQL будет жаловаться:
PG::DatatypeMismatch: ERROR: column "column_name" cannot be cast automatically to type integer
HINT: Specify a USING expression to perform the conversion.
«Подсказка» в основном говорит вам, что вы должны подтвердить, что вы хотите, чтобы это произошло, и как данные должны быть преобразованы. Просто скажите это в своей миграции:
change_column :table_name, :column_name, 'integer USING CAST(column_name AS integer)'
выше будет имитировать то, что вы знаете от других адаптеров базы данных. Если у вас есть нечисловые данные, результаты могут быть неожиданными (но вы конвертируете в целое число, в конце концов).
У меня такая же проблема.
Затем я понял, что у меня есть строковое значение по умолчанию для столбца, который я пытался изменить.
Удаление значения по умолчанию сделало ошибку уйти:)
2
автор: Valdenir Antoglioli Junior
Вы можете сделать это так:
change_column :table_name, :column_name, 'integer USING CAST(column_name AS integer)'
или попробуйте этот:
change_column :table_name, :column_name, :integer, using: 'column_name::integer'
Если вам интересно узнать больше об этой теме прочитайте эту статью:https://kolosek.com/rails-change-database-column
Если вы случайно или не смешали целые числа с текстовыми данными, вы должны сначала выполнить команду ниже update (если не выше alter table не удастся):
UPDATE the_table SET col_name = replace(col_name, 'some_string', '');
Если вы работаете над средой разработки(или для производства env. это может быть резервное копирование ваших данных), а затем сначала очистить данные из поля БД или установить значение 0.
UPDATE table_mame SET field_name= 0;
после этого выполнить запрос ниже и после успешного выполнения запроса, к schemamigration и после этого запустить сценарий миграции.
ALTER TABLE table_mame ALTER COLUMN field_name тип числовой (10,0) используя field_name:: numeric;
Я думаю, это поможет вам.
Нет неявного (автоматического) приведения из text or varchar в integer (т.е. вы не можете передать varchar функции, ожидающей integer или назначить varchar поле в integer one), поэтому вы должны указать явное приведение, используя ALTER TABLE… ALTER COLUMN… TYPE… USING:
ALTER TABLE the_table ALTER COLUMN col_name TYPE integer USING (col_name::integer);
Обратите внимание, что в ваших текстовых полях могут быть пробелы; в этом случае используйте:
ALTER TABLE the_table ALTER COLUMN col_name TYPE integer USING (trim(col_name)::integer);
для удаления пробелов перед преобразованием.
Это должно было быть очевидно из сообщения об ошибке, если команда была запущена в psql, но возможно, что PgAdmin-III не показывает вам полную ошибку. Вот что произойдет, если я проверю это в psql на PostgreSQL 9.2:
=> CREATE TABLE test( x varchar );
CREATE TABLE
=> insert into test(x) values ('14'), (' 42 ');
INSERT 0 2
=> ALTER TABLE test ALTER COLUMN x TYPE integer;
ERROR: column "x" cannot be cast automatically to type integer
HINT: Specify a USING expression to perform the conversion.
=> ALTER TABLE test ALTER COLUMN x TYPE integer USING (trim(x)::integer);
ALTER TABLE
Спасибо @muistooshort за добавление USING ссылку.
Смотрите также этот связанный вопрос; речь идет о миграции Rails, но основная причина та же, и ответ применим.
Если ошибка все еще возникает, то она может быть связана не со значениями столбца, а с индексами по этому столбцу или значениям по умолчанию для столбца может произойти сбой приведения типов. Индексы должны быть удалены до ALTER COLUMN и воссозданы после. Значения по умолчанию должны быть соответствующим образом изменены.
When converting a table column from varchar to integer I ran into a problem.
[code lang=text]
SQLSTATE[42804]: Datatype mismatch: 7 ERROR: default for column «column_name» cannot be cast to type integer
[/code]
The solution I could find on (Stackoverflow)[http://stackoverflow.com/questions/13170570/change-type-of-varchar-field-to-integer-cannot-be-cast-automatically-to-type-i] was not working:
[code lang=sql]
ALTER TABLE the_table ALTER COLUMN col_name TYPE integer USING (col_name::integer);
[/code]
Looking closer at the error I realised – as is often the case – the error was indicating exactly what the problem was. The default of the column could not be converted.
Not knowing how to convert the default, I simply changed it to something that could be converted:
[code lang=sql]
ALTER TABLE the_table ALTER COLUMN col_name SET DEFAULT 0;
[/code]
Despite it being a varchar column, the integer value 0 was accepted. After which the earlier CAST worked.
Everything is as it should be
Я пытаюсь изменить столбец пола на целое число в своем приложении rails. Говорят, что при использовании postgresql мы должны писать немного по-другому. то есть
change_column :users, :gender, :integer, using: 'gender::integer'
Или
change_column :users, :gender, 'integer USING CAST(gender AS integer)'
Однако в моем случае вышеперечисленное все еще не работает и получило следующую ошибку.
PG::DatatypeMismatch: ERROR: default for column "gender" cannot be cast automatically to type integer
: ALTER TABLE "users" ALTER COLUMN "gender" TYPE integer USING gender::integer
Пожалуйста, скажите мне, почему это не работает. Или какие-то странные вещи у меня есть? Например опечатка.
Моя среда
- Рубин: 2.5.0
- Рельсы: 5.1.6
- Постгрес: 11.1
1 ответ
Судя по сообщению об ошибке, которое вы видите, Postgres не знает, как сохранить значение по умолчанию, которое вы установили при изменении типа базы данных на целочисленный. Я бы предложил:
- Удаление значения по умолчанию
- Изменение типа данных в столбце
- Добавление значения по умолчанию в новый тип
Возможно, вы сможете выполнить шаги 2 и 3 в одном вызове. Вы захотите использовать что-то вроде приведенного ниже при миграции вверх:
def up
execute "ALTER TABLE users ALTER gender DROP DEFAULT;"
change_column :users, :gender, :integer, using: 'gender::integer', default: 0
end
1
George S
17 Фев 2019 в 18:37