Eu tenho um erro estranho ao importar um banco de dados com backup do meu ambiente de produção para o meu ambiente de desenvolvimento.
o cenário é o seguinte:
- Postgres 13.x
- PGAdmin 4
- os arquivos de migração são gerados pelo dbmate e criam as mesmas tabelas em ambos os ambientes. Pelo menos é o que penso e espero.
- o backup é feito via PGAdmin exportando SOMENTE os dados (sem esquema, sem nada)
OK, essa foi a parte fácil.
Minha importação usando o PgAdmin funciona quase bem com uma única exceção em uma tabela específica. Essa tabela usa um tipo definido pelo usuário para uma de suas colunas e define uma restrição que usa esse tipo definido pelo usuário dentro de uma função quando a restrição é verificada.
A coisa toda se parece mais ou menos com isto:
CREATE TYPE status AS ENUM ('ACTIVE','DEACTIVE');
CREATE TABLE my_table (
id varchar(36) NOT NULL PRIMARY KEY,
created_at timestamp NOT NULL,
updated_at timestamp NOT NULL,
...
total decimal NOT NULL,
value JSONB NOT NULL,
state status
);
CREATE OR REPLACE FUNCTION complex_constraint_function(value JSONB, total decimal, state status)
RETURNS boolean AS $$
DECLARE
result boolean default false;
BEGIN
IF state = 'ACTIVE'::status THEN
BEGIN
--do some complex JSONB stuff
-- return true if everything is fine
RETURN true;
END;
ELSE
RETURN false;
END IF;
END;
$$ LANGUAGE plpgsql;
ALTER TABLE my_table
ADD CONSTRAINT check_complex_constraint
CHECK (complex_constraint_function(value, total, state));
Estou usando vários tipos definidos pelo usuário em meu banco de dados e todos funcionam bem. E estou usando várias restrições que usam funções e todas funcionam bem. Mas esta tabela em particular está me dando dor de cabeça.
Ao importar o backup via PGAdmin para o ambiente de desenvolvimento, recebo o seguinte erro quando a restrição está sendo verificada
pg_restore: error: COPY failed for table "my_table": ERROR: type "status" does not exist
LINE 1: state = 'ACTIVE'::status
^
QUERY: state = 'ACTIVE'::status
CONTEXT: PL/pgSQL function public.complex_constraint_function(jsonb,numeric,public.status) line 6 at IF
Eu verifiquei duas vezes e três vezes se esse tipo ENUM existe em ambos os bancos de dados (e honestamente não há outra maneira, já que o banco de dados de desenvolvimento é reconstruído regularmente usando dbmate). Sinceramente, não tenho ideia de como isso pode ser. Como ao executar meus casos de teste com o dev-db, essa restrição existe (estou testando isso explicitamente).
Alguém já viu algo assim? Ou alguma idéia de como depurar isso (exceto eliminar a restrição)?
Obrigado