Pg datatypemismatch ошибка столбец нельзя автоматически привести к типу integer

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 experienced this error when I tried to run rake db:migrate.
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:

PG::DatatypeMismatch: ERROR: column «developer_id» cannot be cast automatically to type integer
HINT: You might need to specify «USING developer_id::integer».

I am changing my sqlite3 database to PostgreSQL for deployment in Heroku.
I am assuming the error is coming from the db/migrate file.rb that has the developer_id column specified.

  def change
    change_column :entries, :developer_id, :integer
  end
end

I will add any other document that may help locate the problem.

Нет неявного (автоматического) перевода из text или varchar в integer (т.е. вы не можете передать varchar функции, ожидающей integer, или назначьте поле varchar для integer one), поэтому вы должны указать явное преобразование, используя ALTER TABLE… ALTER COLUMN… TYPE… ИСПОЛЬЗОВАНИЕ:

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, но основная причина — то же самое и ответ применяется.

У меня есть небольшая таблица, и определенное поле содержит тип «, отличающийся«. Я пытаюсь изменить его на « Integer«, но он дает ошибку, что кастинг невозможен.

Есть ли способ обойти это или я должен просто создать другую таблицу и принести записи в нее с помощью запроса.

Поле содержит только целые значения.

4b9b3361

Ответ 1

Нет неявного (автоматического) перевода из text или varchar в integer (т.е. вы не можете передать varchar функции, ожидающей integer, или назначьте поле varchar для integer one), поэтому вы должны указать явное преобразование, используя ALTER TABLE… ALTER COLUMN… TYPE… ИСПОЛЬЗОВАНИЕ:

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, но основная причина — то же самое и ответ применяется.

Ответ 2

этот работал у меня.

изменить столбец 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.

привязан к

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

Ответ 3

Вы можете сделать это как:

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

Ответ 4

Попробуйте это, это сработает наверняка.

При написании 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)'

Вышеупомянутое будет имитировать то, что вы знаете из других адаптеров баз данных. Если у вас есть нечисловые данные, результаты могут быть неожиданными (но вы все равно конвертируете в целое число).

Ответ 5

У меня такая же проблема.
Чем я понял, у меня было строковое значение по умолчанию для столбца, который я пытался изменить.
При удалении значения по умолчанию ошибка исчезла:)

Ответ 6

Если вы случайно или не смешали целые числа с текстовыми данными, вы должны сначала выполнить команду обновления (если не выше таблицы alter не получится):

UPDATE the_table SET col_name = replace(col_name, 'some_string', '');

Ответ 7

Если вы работаете в среде разработки (или для продакшен среды, это может быть резервное копирование ваших данных), то сначала удалите данные из поля БД или установите значение 0.

UPDATE table_mame SET field_name= 0;

После этого для запуска приведенного ниже запроса и после успешного выполнения запроса к схеме-миграции и после этого запустите сценарий миграции.

ALTER TABLE table_mame ALTER COLUMN field_name TYPE numeric(10,0) USING field_name::numeric;

Я думаю, что это поможет вам.

    Изменение типа данных столбца таблицы в PostgreSQL делается с использованием команды ALTER TABLE в комбинации с ALTER COLUMN. Согласно документации эта операция «будет успешна, только если все существующие значения в столбце могут быть неявно приведены к новому типу». Но это не совсем верно. Например, мешают еще связанные с этим столбцом ограничения DEFAULT и CHECK, или несовместимость типов данных. Тип VARCHAR(4) можно легко сменить на CHAR(4) или наоборот, а попытка сменить на INTEGER приведет к ошибке. И эта ошибка будет даже для пустой таблицы.

    Если PostgreSQL не справляется с приведением типов, то нужно ему подсказать, как это сделать. У ALTER COLUMN для этого есть дополнительный параметр USING. Рассмотрим решение «трудностей» изменение типа данных столбца таблицы с CHARVARCHAR на INTEGER на примере. Создадим таблицу «test»

CREATE TABLE test
( 
  id     SERIAL PRIMARY KEY, 
  name   TEXT, 
  status CHAR(1) NOT NULL DEFAULT '0'
);

и изменим тип столбца status с CHAR(1) на INTEGER.

Если команда

ALTER TABLE test ALTER COLUMN status TYPE CHAR(10);

будет успешной, то команда

ALTER TABLE test ALTER COLUMN status TYPE INTEGER;

приведет к ошибке «столбец status нельзя автоматически привести к типу integer». Нам надо: удалить ограничение DEFAULT, поменять тип с явным приведением к INTEGER и создать новое ограничение DEFAULT:

ALTER TABLE test ALTER COLUMN status DROP DEFAULT;
ALTER TABLE test ALTER COLUMN status TYPE INTEGER USING (status::INTEGER);
ALTER TABLE test ALTER COLUMN status SET DEFAULT 0;

Посмотрим, что у нас получилось:

Структура таблицы после изменения типа столбца с CHAR на INTEGER

Тип поля status сменился на INTEGER.

    Параметр USING позволяет использовать более сложные конструкции, чем простое преобразование типов. Например, в него можно вставить CASE или вызов функции. Создадим таблицу и вставим в нее несколько строк

CREATE TABLE test
(
  id SERIAL PRIMARY KEY, 
  name TEXT, 
  status CHAR(1)
);

INSERT INTO test(name, status) 
  VALUES ('цифра 0', '0'),
         ('цифра 3', '3'),
         ('цифра 9', '9'),
         ('буква X', 'X');

Наличие строки со status равным «X» при изменении типа столбца status на INTEGER приведет «USING (status::INTEGER)» к ошибке «неверный синтаксис для типа integer: X». Итак задача: значения столбца равные «0» преобразовать к -1, цифры от «1» до «9» в число, а все остальные символы в их ASCII-код:

ALTER TABLE test 
  ALTER COLUMN status TYPE INTEGER USING (CASE 
                                            WHEN status = '0'  THEN -1
                                            WHEN status ~ 'd' THEN status::INTEGER 
                                            ELSE ASCII(status) 
                                          END);

Мы видим снова успешный результат:

Результат использования USING с CASE и вызовом функции

  • Peugeot partner tepee коды ошибок
  • Peugeot boxer ошибка p2291
  • Peugeot 3008 коды ошибок
  • Peugeot 207 ошибка p2178
  • Peugeot 207 ошибка p1804