Como criar uma cópia da tabela com a data atual no nome da tabela no Postgres

Como criar uma cópia da tabela com a data atual no nome da tabela no Postgres
Photo by benjamin lehman / Unsplash

Uma maneira de resolver o problema é utilizar o shell para "montar" a data e criar a tabela com o resultado de um alias para data.

Segue um exemplo, de como será o resultado do nome da tabela:

echo "tbl_xpto_$(printf '%(%d_%m_%Y)T' -1)"

A saída para este comando acima é o seguinte:

tbl_xpto_07_03_2024

Verifique que os valores mudam de acordo com a data atual, então dependendo do dia que executar o comando, pode receber outro resultado, pois no comando acima, estamos formatando uma saída de data, no formato (dd_MM_YYYY)

Pronto, agora que já sabe como vai ser o nome da tabela, basta utilizar esta mesma lógica para executar este comando utilizando o psql.

Segue um exemplo:

Uma maneira de resolver o problema é utilizar o shell para "montar" a data e criar a tabela com o resultado de um alias.

Segue um exemplo, de como será o resultado do nome da tabela:

echo "tbl_xpto_$(printf '%(%d_%m_%Y)T' -1)"
Formatador Descrição
%d dia
%m Mês
%Y (maiúsculo) Ano com 4 dígitos

Uma maneira de resolver é utilizando uma stored procedure, basta criar uma procedure e depois executar esta stored procedure.

CREATE OR REPLACE PROCEDURE CRIAR_TABELA_DATA_HOJE() LANGUAGE plpgsql AS
$func$
BEGIN
    execute format('create table tbl_xpto%s as table tbl_xpto', to_char(now(), 'DD_MM_YYYY'));
END;
$func$;

Um caso de uso real

Vamos criar uma tabela usuario e inserir 4 usuários.

CREATE TABLE IF NOT EXISTS usuario (
    id UUID DEFAULT gen_random_uuid(),
    nome VARCHAR(32)
);

INSERT INTO usuario (nome) VALUES ('a');
INSERT INTO usuario (nome) VALUES ('b');
INSERT INTO usuario (nome) VALUES ('c');
INSERT INTO usuario (nome) VALUES ('d');

Agora queremos criar a nossa stored_procedure que vai criar uma nova tabela usuario07_03_2024. A stored_procedure deve ser da seguinte forma:

CREATE OR REPLACE PROCEDURE CRIAR_TABELA_DATA_HOJE() LANGUAGE plpgsql AS
$func$
BEGIN
    execute format('create table usuario%s as table usuario', to_char(now(), 'DD_MM_YYYY'));
END;
$func$;

Repare que no comando acima, estamos formatando uma data para o formato de string desejado, e o operador possui o mesmo funcionando do formatador de saída no C. Então o resultado será uma data formatada no padrão (DD_MM_YYYY), separada por underline (_)

Depois para executar a stored_procedure basta executar:

CALL CRIAR_TABELA_DATA_HOJE()

Ao executar o comando deve existir uma nova tabela em seu esquema do banco de dados.

Para verificar, basta rodar o comando \dt

               List of relations
 Schema |       Name        | Type  |  Owner   
--------+-------------------+-------+----------
 public | usuario           | table | ***
 public | usuario07_03_2024 | table | ***
(2 rows)

=# select * from usuario08_03_2024 ;
                  id                  | nome 
--------------------------------------+------
 2d668121-39b4-4397-ada0-3760f1adccc3 | a
 51f3ec21-61bc-4b42-b7d2-99368b8dd91e | b
 bbbd5aab-db12-4214-a7cc-84149812e94a | c
 6e441abf-dc2e-48c1-a3af-d9cd3a76172f | d
(4 rows)

Uma solução utilizando o shell

Uma segunda maneira de resolver o problema é utilizar o shell para "montar" a data e criar a tabela com o resultado de um alias.

Segue um exemplo, de como será o resultado do nome da tabela:

echo "tbl_xpto_$(printf '%(%d_%m_%Y)T' -1)"
Formatador Descrição
%d dia
%m Mês
%Y (maiúsculo) Ano com 4 dígitos

A tabela completa dos formatadores pode ser vista na documentação do comando date

Pronto, agora que já sabe como vai ser o nome da tabela, basta utilizar esta mesma lógica para executar este comando utilizando o psql.

Segue um exemplo:

psql -U <usuario> <nome-db> -c "CREATE TABLE tbl_xpto_$(printf '%(%d_%m_%Y)T' -1) AS TABLE tbl_01"

Repare que no comando acima, estamos passando o parâmetro -c e no argumento deste parâmetro passamos o comando DDL que cria a cópia da tabela.

Substitua o valor <nome-db> pelo nome do seu banco de dados. Assim como valor do <usuario> pelo nome do seu usuário correspondente à sua configuração do banco de dados.

Vale ressaltar também que as regras de formação de nome das tabelas do postgres não é possível ter nomes com - (dash), mas se gostaria de utilizar o dash no nome da tabela, pode utilizar a forma de nomes de tabelas literais (onde o nome da tabela deve ser envolvido em aspas duplas). Para saber as regras leia a documentação da sintaxe das palavras chaves.

Após a execução com sucesso, deve ser solicitado a senha do banco de dados.

Ao final, se tudo ocorrer com sucesso, deve ser exibido a quantidade de linhas contida na tabela.

Como referências para esta resposta utilizei esta publicação.

Além da documentação do Postgres