Alterar o tipo de dados da coluna no Amazon Redshift

85

Como alterar o tipo de dados da coluna no banco de dados Amazon Redshift?

Não consigo alterar o tipo de dados da coluna no Redshift; existe alguma maneira de modificar o tipo de dados no Amazon Redshift?

user1485267
fonte
6
"Create table as select ..." E projete sua nova tabela com o melhor tipo de coluna.
Guy

Respostas:

137

Conforme observado na documentação ALTER TABLE , você pode alterar o comprimento das VARCHARcolunas usando

ALTER TABLE table_name
{
    ALTER COLUMN column_name TYPE new_data_type 
}

Para outros tipos de coluna, tudo que posso pensar é adicionar uma nova coluna com um tipo de dados correto, inserir todos os dados da coluna antiga em uma nova e, finalmente, eliminar a coluna antiga.

Use um código semelhante a este:

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;

Haverá uma mudança de esquema - a coluna recém-adicionada será a última em uma tabela (isso pode ser um problema com a COPYinstrução, tenha isso em mente - você pode definir a ordem das colunas com COPY)

Tomasz Tybulewicz
fonte
4
ALTER ou qualquer instrução DDL é confirmada imediatamente, independentemente de estar envolvida em uma transação ou não.
Raniendu Singh
@RanienduSingh alguns bancos de dados suportam instruções DDL transacionais. Não encontrei uma lista oficial, mas a maioria das instruções DDL no Redshift parecem funcionar em uma transação. No entanto, acho que reordenar as operações semelhantes à abordagem descrita aqui (renomear, adicionar, atualizar, descartar) pode ser mais robusto: simple.com/engineering/safe-migrations-with-redshift
Matt Good
1
É importante notar que agora é possível aumentar o tamanho das colunas varchar - veja a resposta do user0000 abaixo e o link para os documentos ( docs.aws.amazon.com/redshift/latest/dg/r_ALTER_TABLE.html )
willis
1
@Tomasz Tybulewicz, você poderia atualizar sua resposta, incluindo a resposta do usuário0000? Sua resposta estava correta na época, mas eu me enganei. Felizmente, também li a resposta do
usuário0000
43

para evitar a mudança de esquema mencionada 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
fonte
1
Este é o método que usamos também para evitar declaração de cópia desalinhada.
SMB
1
Lembre-se de que todas as visualizações que costumavam ser selecionadas na tabela antiga continuam apontando para a tabela antiga. A drop tableconsulta mostrará o erro de dependência que pode ser, mas não deve, ser ignorado.
1
Obrigado por isso, foi muito útil. Eu usei em uma tabela com 31 milhões de linhas e levou apenas 3 minutos usando o tipo dc1.large. Ótimo! Eu também usei uma forma um pouco mais simples:INSERT INTO <TABLE_NAME> SELECT * FROM <TABLE_NAME>_OLD;
Tom
Encapsular com TRANSACTION é muito importante
louis_guitton
16

(Atualização recente) É possível alterar o tipo das colunas varchar no Redshift.

ALTER COLUMN column_name TYPE new_data_type

Exemplo:

CREATE TABLE t1 (c1 varchar(100))

ALTER TABLE t1 ALTER COLUMN c1 TYPE varchar(200)

Aqui está o link de documentação

user0000
fonte
Isso funciona perfeitamente. Uma linha legal que não mudará o esquema de forma alguma, mas atualizará o tipo de dados. Esta deve ser a nova resposta atualizada!
Timothy Mcwilliams
8

Se você não quiser alterar a ordem das colunas , uma opção será criar uma tabela temporária, eliminar e criar uma nova com o tamanho desejado e, em seguida, agrupar novamente os dados.

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;

O único problema de recriar a tabela é que você precisará conceder novamente as permissões e, se a tabela for muito maior, isso demorará um pouco.

Franzi
fonte
1
Isso é muito semelhante à resposta existente de Wolli para renomear e copiar os dados da tabela antiga para o novo esquema. Ambos manterão a ordem das colunas, mas esta solução com uma tabela temporária requer a cópia dos dados duas vezes. Uma para copiar para a tabela temporária e outra para copiar de volta para a nova tabela. Renomear a tabela deve ser mais rápido executando apenas uma cópia.
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
fonte
3

O Redshift, sendo um banco de dados colunar, não permite que você modifique o tipo de dados diretamente; no entanto, abaixo está uma abordagem que mudará a ordem das colunas.

Passos -

1.Alter table adiciona newcolumn à tabela 2.Atualize o valor newcolumn com o valor oldcolumn 3.Alter table para eliminar a oldcolumn 4.alter table para renomear columnn para oldcolumn

Se você não quiser alterar a ordem das colunas, a solução seria

1. criar tabela temporária com novo nome de coluna

  1. copie os dados da tabela antiga para a nova.

  2. largar mesa velha

  3. renomear newtable para oldtable

  4. Uma coisa importante é criar uma nova tabela usando o comando like em vez de criar simplesmente.

Rama Krishna
fonte
2

Este método funciona para converter uma coluna (grande) int em um 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;
confortável hoje
fonte
0

DESCARREGUE e COPIE com a estratégia de renomeação de tabela deve ser a maneira mais eficiente de fazer esta operação se for importante manter a estrutura da tabela (ordem das linhas).

Aqui está um exemplo que adiciona a esta resposta.

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
fonte
-2

para atualizar a mesma coluna em redshift isso funcionaria bem

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

você pode ter várias cláusulas em where usando e, de modo a remover qualquer confusão para sql

Felicidades!!

Achin Saharawat
fonte