call plpython3u function in a plpgsql function

69 Views Asked by At

I have a simple function in plpython3u that makes a request to a server, like this:

CREATE OR REPLACE FUNCTION public.f_request_http(
    metodo                  TEXT
    , url                   TEXT
    , body                  TEXT
    , headers               TEXT
    , timeout               INTEGER DEFAULT 30
    
)
 RETURNS record
 LANGUAGE plpython3u
AS $function$
    import requests
    import json

    if timeout > 300:
        raise Exception("Parametro [timeout] deve ser menor que 300")
    try:
        if headers != '':
            reqHeaders = json.loads(headers)
        else:
            reqHeaders = None

        reqTimeout = timeout

        if reqHeaders != None and reqHeaders["Content-Type"] == 'application/json':
            if body == '':
                reqBody = None
            else:
                reqBody = json.loads(body, strict=False)
            response = requests.request(metodo, url, headers=reqHeaders, json=reqBody, timeout=reqTimeout)
        else:
            response = requests.request(metodo, url, headers=reqHeaders, data=body, timeout=reqTimeout)

        code = response.status_code
        mensagem = response.text
        respHeaders = response.headers
    except Exception as e:
        code = 999
        mensagem = e
    return (code, mensagem, respHeaders)
 $function$;

As you can see, when using the function, we must use some parameters. and I want to call it inside this function here:

CREATE OR REPLACE FUNCTION f_cotacao() 
RETURNS JSON
AS $$
DECLARE
    rec             RECORD;
    json_req        JSON;
    json_produto    JSON;
    vrequest        JSON;
BEGIN 
    FOR rec IN     
        SELECT 
          
        , b.url_endpoint 
        , eb.id_empresa
        , e.nome_empresa 
        , eb.id_bandeira
        , UNNEST(STRING_TO_ARRAY(eb.codigo_empresa,';')) codigo_empresa
        , f.id_fornecedor 
        CASE 
            WHEN fpe.tipo_frete = 0 THEN '1C'
            WHEN fpe.tipo_frete = 1 THEN '1F'
        END frete
        , f.apelido_fornecedor AS plant
        , ARRAY_TO_STRING(ARRAY_AGG(pb.codigo_produto), ';') lista_codigo_produto
    FROM bandeira b
     fornecedor_produto_empresa fpe ON fpe.id_empresa = eb.id_empresa 
        INNER JOIN fornecedor_bandeira fb ON fb.id_fornecedor = fpe.id_fornecedor 
        INNER JOIN fornecedor f ON f.id_fornecedor = fb.id_fornecedor 
        INNER JOIN produto_empresa pe ON pe.id_empresa = fpe.id_empresa AND pe.id_produto = fpe.id_produto 
        INNER JOIN produto p ON p.id_produto = fpe.id_produto 
        INNER JOIN produto_bandeira pb ON pb.id_bandeira = b.id_bandeira AND pb.id_produto = fpe.id_produto 
    WHERE e.registro_ativo 
    AND fpe.registro_ativo 
    AND pe.registro_ativo 
    AND p.registro_ativo 
    GROUP BY  
        b.id_bandeira
        , b.codigo_bandeira
        , b.nome_bandeira
        , eb.id_empresa
        , e.nome_empresa 
        , eb.id_bandeira
        , eb.codigo_empresa
        , f.id_fornecedor 
        , f.apelido_fornecedor 
        , f.nome_fornecedor 
        , fpe.tipo_frete 
            
   LOOP
       -- Monta o json de empresa
        IF (rec.codigo_bandeira = '00001') THEN
          WITH sub_produto AS (
              SELECT JSON_AGG(r.json_produto) FROM (
                    SELECT  
                        JSON_BUILD_OBJECT(
                            'materialId', UNNEST(STRING_TO_ARRAY(rec.lista_codigo_produto, ';')),
                            'paymentTermSAPId', 'Z001',
                            'salesUnit', 'L' 
                        ) json_produto
                ) r
          )
            -- Monta o JSON completo 
            SELECT 
                JSON_BUILD_OBJECT(
                    'customerId', SPLIT_PART(rec.codigo_empresa, '|', 1),
                    'division', 'LF',
                    'shippingCondition', rec.frete,
                    'distributionChannel', 'V ',
                    'salesOrganization',  SPLIT_PART(rec.codigo_empresa, '|', 2),
                    'requestedDeliveryDate', CURRENT_TIMESTAMP,
                    'plant', rec.plant,
                    'products', (json_produto)  
                )
            INTO json_req;
            RAISE NOTICE '%', json_req;
           
           -- chama a funcao que faz requisicao no csonline
        SELECT  * 
        INTO    vrequest
        FROM    public.f_request_http(
                'GET', 
                rec.url_endpoint,
                json_req, 
                '{"Authorization": "Bearer token": "application/json"}' ) f; 
    
        RAISE NOTICE '%', vrequest;
    
        END IF;
    END LOOP;
    RETURN json_req;
END;
$$ LANGUAGE plpgsql;

I'm very new to plpgsql and plpython, so as you can see, I made a call with:

SELECT  * 
        INTO    vrequest
        FROM    public.f_request_http(param,param,param,param)

but I get the error:

ERROR: function public.f_request_http(unknown, text, json, unknown) does not exist
  Tip: No function matches the given name and argument types. You might need to add explicit type casts.
  Where: PL/pgSQL function f_cotacao() line 83 at SQL statement

How can I make a call to my plpython function within the plpgsql function? send me some documents to read

0

There are 0 best solutions below