Tenho uma tabela source_aepsfinswitch_tmp_details
contendo um conjunto de dados muito grande. Meu objetivo é particionar essa tabela em duas partições com base na reconciliation_date_time
coluna:
- Se
reconciliation_date_time
forNULL
, a linha deve ir para uma partição. - Se
reconciliation_date_time
forNOT NULL
, a linha deve ir para outra partição.
Devido ao tamanho dos dados, quero evitar usar INSERT INTO
instruções para mover os dados manualmente. Em vez disso, tentei a seguinte abordagem:
BEGIN;
CREATE TABLE IF NOT EXISTS public.source_aepsfinswitch_tmp_details_new (
LIKE public.source_aepsfinswitch_tmp_details EXCLUDING CONSTRAINTS,
PRIMARY KEY (uniqueid, reconciliation_date_time)
) PARTITION BY RANGE (reconciliation_date_time);
ALTER TABLE public.source_aepsfinswitch_tmp_details RENAME TO source_aepsfinswitch_tmp_details_old;
ALTER TABLE public.source_aepsfinswitch_tmp_details_new RENAME TO source_aepsfinswitch_tmp_details;
ALTER TABLE public.source_aepsfinswitch_tmp_details ATTACH PARTITION public.source_aepsfinswitch_tmp_details_old DEFAULT;
COMMIT;
Entretanto, quando executo isso, recebo o seguinte erro:
SQL Error [42804]: ERROR: column "reconciliation_date_time" in child table must be marked NOT NULL
Como posso atingir meu objetivo sem encontrar esse erro? Tentei LIST e RANGE, mas nenhum funcionou. Existe uma maneira de particionar a tabela conforme descrito sem exigir que a coluna reconciliation_date_time
seja NOT NULL
? Existe alguma maneira de dividir a tabela em partições sem usar INSERT INTO
?
Graças à sugestão de Laurenz Albe , consegui anexar a partição. No entanto, como posso criar duas tabelas com base na tabela pai? Estou recebendo o seguinte erro ao executar a consulta abaixo:
CREATE TABLE IF NOT EXISTS public.source_aepsfinswitch_tmp_details_new (LIKE public.source_aepsfinswitch_tmp_details EXCLUDING CONSTRAINTS) PARTITION BY LIST (reconciliation_date_time);
ALTER TABLE public.source_aepsfinswitch_tmp_details RENAME TO source_aepsfinswitch_tmp_details_old;
ALTER TABLE public.source_aepsfinswitch_tmp_details_new RENAME TO source_aepsfinswitch_tmp_details;
ALTER TABLE public.source_aepsfinswitch_tmp_details ATTACH PARTITION public.source_aepsfinswitch_tmp_details_old DEFAULT;
CREATE TABLE IF NOT EXISTS public.source_aepsfinswitch_tmp_details_null PARTITION OF public.source_aepsfinswitch_tmp_details FOR VALUES IN (NULL);
SQL Error [23514]: ERROR: updated partition constraint for default partition "source_aepsfinswitch_tmp_details_old" would be violated by some row
Acho que esse problema é causado pela chave primária. Criar uma nova partição das mesmas transações que em outras partições no PostgreSQL pode estar causando o erro mencionado acima. Existe uma maneira de lidar com isso?
O problema é a definição da chave primária da tabela particionada. Ela força as colunas a serem
NOT NULL
, o que não funcionaria no seu caso. Simplesmente omita a definição da chave primária na tabela particionada. Você pode definir com segurança uma chave primária nas partições individuais, se quiser.