field type postgresql
Cambiar el tipo de campo varchar a entero: "no se puede convertir automáticamente para escribir entero" (7)
Tengo una tabla pequeña y un cierto campo contiene el tipo " carácter variable ". Intento cambiarlo a " Integer " pero da un error de que no es posible el casting.
¿Hay alguna forma de evitar esto o debería simplemente crear otra tabla y traer los registros en ella usando una consulta?
El campo contiene solo valores enteros.
No hay text
implícita (automática) de text
o varchar
a integer
(es decir, no puede pasar un varchar
a una función que espere un integer
o asignar un campo varchar
a un integer
), por lo que debe especificar un molde explícito utilizando ALTER TABLE ... ALTER COLUMN ... TYPE ... USANDO :
ALTER TABLE the_table ALTER COLUMN col_name TYPE integer USING (col_name::integer);
Tenga en cuenta que puede tener espacios en blanco en los campos de texto; en ese caso, use:
ALTER TABLE the_table ALTER COLUMN col_name TYPE integer USING (trim(col_name)::integer);
para quitar el espacio en blanco antes de convertir.
Esto debería haber sido obvio desde un mensaje de error si el comando se ejecutó en psql
, pero es posible que PgAdmin-III no le muestre el error completo. Esto es lo que sucede si lo psql
en psql
en 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
Gracias @muistooshort por agregar el enlace USING
.
Ver también esta pregunta relacionada ; se trata de migraciones de Rails, pero la causa subyacente es la misma y se aplica la respuesta.
Prueba esto, funcionará con seguridad.
Al escribir las migraciones de Rails para convertir una columna de cadena en un entero, generalmente diría:
change_column :table_name, :column_name, :integer
Sin embargo, PostgreSQL se quejará:
PG::DatatypeMismatch: ERROR: column "column_name" cannot be cast automatically to type integer
HINT: Specify a USING expression to perform the conversion.
La "pista" básicamente le dice que necesita confirmar que desea que esto suceda y cómo se convertirán los datos. Simplemente di esto en tu migración:
change_column :table_name, :column_name, ''integer USING CAST(column_name AS integer)''
Lo anterior imitará lo que sabes de otros adaptadores de bases de datos. Si tiene datos no numéricos, los resultados pueden ser inesperados (pero, después de todo, está convirtiendo a un número entero).
Puedes hacerlo como:
change_column :table_name, :column_name, ''integer USING CAST(column_name AS integer)''
o prueba esto:
change_column :table_name, :column_name, :integer, using: ''column_name::integer''
Si está interesado en obtener más información sobre este tema, lea este artículo: https://kolosek.com/rails-change-database-column
Si accidentalmente o no ha mezclado números enteros con datos de texto, primero debe ejecutar debajo del comando de actualización (si no lo está, alterar la tabla fallará):
UPDATE the_table SET col_name = replace(col_name, ''some_string'', '''');
Si está trabajando en un entorno de desarrollo (o en un entorno de producción puede hacer una copia de seguridad de sus datos), primero borre los datos del campo DB o establezca el valor como 0.
ACTUALIZACIÓN table_mame SET field_name = 0;
Después de eso, ejecute la consulta siguiente y luego de ejecutar con éxito la consulta, a schemamigration y luego ejecute el script migrate.
ALTER TABLE table_mame ALTER COLUMN field_name TYPE numeric (10,0) USANDO field_name :: numeric;
Creo que te ayudará.
Tengo el mismo problema. Entonces me di cuenta de que tenía un valor de cadena predeterminado para la columna que intentaba modificar. Al eliminar el valor predeterminado, el error desapareció :)
this funcionó para mí.
cambiar la columna varchar a int
change_column :table_name, :column_name, :integer
tiene:
PG::DatatypeMismatch: ERROR: column "column_name" cannot be cast automatically to type integer
HINT: Specify a USING expression to perform the conversion.
rechazado
change_column :table_name, :column_name, ''integer USING CAST(column_name AS integer)''