Modificar el tipo de datos de la columna en Amazon Redshift

85

¿Cómo modificar el tipo de datos de la columna en la base de datos de Amazon Redshift?

No puedo alterar el tipo de datos de la columna en Redshift; ¿Hay alguna forma de modificar el tipo de datos en Amazon Redshift?

usuario1485267
fuente
6
"Crear tabla como seleccionar ..." Y diseñe su nueva tabla con el mejor tipo de columna.
Guy

Respuestas:

135

Como se indica en la documentación de ALTER TABLE , puede cambiar la longitud de las VARCHARcolumnas usando

ALTER TABLE table_name
{
    ALTER COLUMN column_name TYPE new_data_type 
}

Para otros tipos de columnas, todo lo que puedo pensar es agregar una nueva columna con un tipo de datos correcto, luego insertar todos los datos de la columna anterior en una nueva y finalmente soltar la columna anterior.

Use un código similar a ese:

ALTER TABLE t1 ADD COLUMN new_column ___correct_column_type___;
UPDATE t1 SET new_column = column;
ALTER TABLE t1 DROP COLUMN column;
ALTER TABLE t1 RENAME COLUMN new_column TO column;

Habrá un cambio de esquema: la columna recién agregada será la última en una tabla (eso puede ser un problema con la COPYdeclaración, téngalo en cuenta: puede definir un orden de columna con COPY)

Tomasz Tybulewicz
fuente
4
ALTER o, para el caso, cualquier declaración DDL se compromete inmediatamente independientemente del tiempo que esté envuelto en una transacción o no.
Raniendu Singh
@RanienduSingh algunas bases de datos admiten declaraciones DDL transaccionales. No he encontrado una lista autorizada, pero la mayoría de las declaraciones DDL en Redshift parecen funcionar en una transacción. Sin embargo, creo que reordenar las operaciones similares al enfoque descrito aquí (cambiar el nombre, agregar, actualizar, eliminar) puede ser más sólido: simple.com/engineering/safe-migrations-with-redshift
Matt Good
1
Vale la pena señalar que ahora es posible aumentar el tamaño de las columnas varchar; consulte la respuesta de user0000 a continuación y el enlace a los documentos ( docs.aws.amazon.com/redshift/latest/dg/r_ALTER_TABLE.html )
willis
1
@Tomasz Tybulewicz, ¿podría actualizar su respuesta, incluida la respuesta de user0000? Su respuesta fue correcta en ese momento, pero me engañé. Afortunadamente, también leí la respuesta de
user0000
43

para evitar el cambio de esquema mencionado por Tomasz:

BEGIN TRANSACTION;

ALTER TABLE <TABLE_NAME> RENAME TO <TABLE_NAME>_OLD;
CREATE TABLE <TABLE_NAME> ( <NEW_COLUMN_DEFINITION> );
INSERT INTO <TABLE_NAME> (<NEW_COLUMN_DEFINITION>)
SELECT <COLUMNS>
FROM <TABLE_NAME>_OLD;
DROP TABLE <TABLE_NAME>_OLD;

END TRANSACTION;
Wolli
fuente
1
Este es el método que usamos también para evitar que la declaración de copia esté desalineada.
smb
1
Tenga en cuenta que las vistas que solían seleccionar de la tabla anterior siguen apuntando a la tabla anterior. La drop tableconsulta mostrará el error de dependencia que se puede omitir pero no se debe omitir.
1
Gracias por esto, fue de gran ayuda. Lo usé en una tabla con 31 millones de filas y solo tomó 3 minutos usando el tipo dc1.large. ¡Excelente! También utilicé una forma un poco más simple:INSERT INTO <TABLE_NAME> SELECT * FROM <TABLE_NAME>_OLD;
Tom
Encapsular con TRANSACTION es muy importante
louis_guitton
16

(Actualización reciente) Es posible modificar el tipo de columnas varchar en Redshift.

ALTER COLUMN column_name TYPE new_data_type

Ejemplo:

CREATE TABLE t1 (c1 varchar(100))

ALTER TABLE t1 ALTER COLUMN c1 TYPE varchar(200)

Aquí está el enlace de documentación

user0000
fuente
Esto funciona perfectamente. Un buen trazador de líneas que no cambiará el esquema en absoluto, pero actualizará el tipo de datos. ¡Esta debería ser la nueva respuesta actualizada!
Timothy Mcwilliams
8

Si no desea cambiar el orden de las columnas , una opción será crear una tabla temporal, soltar y crear la nueva con el tamaño deseado y luego volver a agrupar los datos.

CREATE TEMP TABLE temp_table AS SELECT * FROM original_table;
DROP TABLE original_table;
CREATE TABLE original_table ...
INSERT INTO original_table SELECT * FROM temp_table;

El único problema para recrear la tabla es que necesitará otorgar permisos nuevamente y si la tabla es demasiado grande, tomará un tiempo.

Franzi
fuente
1
Esto es bastante similar a la respuesta existente de Wolli para cambiar el nombre y luego copiar los datos de la tabla anterior en el nuevo esquema. Ambos mantendrán el orden de las columnas, pero esta solución con una tabla temporal requiere copiar los datos dos veces. Una vez para copiar en la tabla temporal y otra para volver a copiar a la nueva tabla. Cambiar el nombre de la tabla debería ser más rápido al realizar solo una copia.
Matt Good
4
ALTER TABLE publisher_catalogs ADD COLUMN new_version integer;

update publisher_catalogs set new_version = CAST(version AS integer);
ALTER TABLE publisher_catalogs DROP COLUMN version RESTRICT;
ALTER TABLE publisher_catalogs RENAME new_version to version;
Anand Kumar
fuente
3

Redshift, al ser una base de datos en columnas, no le permite modificar el tipo de datos directamente, sin embargo, a continuación se muestra un enfoque que cambiará el orden de las columnas.

Pasos -

1.Alterar la tabla agrega una nueva columna a la tabla 2.Actualiza el valor de la nueva columna con el valor de la columna anterior 3.Altera la tabla para eliminar la columna anterior 4.Altera la tabla para cambiar el nombre de la columna a la antigua

Si no desea alterar el orden de las columnas, la solución sería

1.crear tabla temporal con un nuevo nombre de columna

  1. copiar datos de la tabla anterior a la nueva.

  2. soltar mesa vieja

  3. cambiar el nombre de la tabla nueva a tabla antigua

  4. Una cosa importante es crear una nueva tabla usando el comando like en lugar de crear simplemente.

Rama krishna
fuente
2

Este método funciona para convertir una columna int (grande) en un varchar

-- Create a backup of the original table
create table original_table_backup as select * from original_table;

-- Drop the original table, and then recreate with new desired data types
drop table original_table;

create table original_table (
  col1 bigint,
  col2 varchar(20) -- changed from bigint
);

-- insert original entries back into the new table
insert into original_table select * from original_table_backup;

-- cleanup
drop original_table_backup;
comfytoday
fuente
0

DESCARGAR y COPIAR con la estrategia de cambio de nombre de la tabla debería ser la forma más eficiente de realizar esta operación si es importante conservar la estructura de la tabla (orden de filas).

Aquí hay un ejemplo que se agrega a esta respuesta.

BEGIN TRANSACTION;

ALTER TABLE <TABLE_NAME> RENAME TO <TABLE_NAME>_OLD;
CREATE TABLE <TABLE_NAME> ( <NEW_COLUMN_DEFINITION> );
UNLOAD ('select * from <TABLE_NAME>_OLD') TO 's3://bucket/key/unload_' manifest;
COPY <TABLE_NAME> FROM 's3://bucket/key/unload_manifest'manifest;

END TRANSACTION;
Alok Kumar Singh
fuente
-2

para actualizar la misma columna en corrimiento al rojo, esto funcionaría bien

UPDATE table_name 
SET column_name = 'new_value' WHERE column_name = 'old_value'

puede tener varias cláusulas en donde mediante el uso de y, para eliminar cualquier confusión para sql

¡¡salud!!

achin saharawat
fuente