Pass values from python code to a postgresql query

Question:

I read an excel-file, put the data in a pandas dataframe and then i wanna put the data in a postgresql database.
Problem is getting the pandas-value to the postgresql-database.

For putting the data into psql-database i use:

cursor.execute('CALL controldubbel2(%s, %s, %s, %s, %s, %s, %s)', (datum2, naamtegen, tegenrekening, omschrijving1, bedrag, saldo, code))

But then i get this error:

Exception has occurred: UndefinedFunction
procedure controldubbel2(unknown, unknown, unknown, unknown, integer, numeric, unknown) does not exist
LINE 1: CALL controldubbel2('2023-01-05', 'Betaalverzoek...
             ^
HINT:  No procedure matches the given name and argument types. You might need to add explicit type casts.

Strange thing is that this code works well:

cursor.execute(f"SELECT controldubbel2('{datum2}', '{naamtegen}', '{tegenrekening}', '{omschrijving1}', '{bedrag}', '{saldo}', '{code}')")

But i understand that this is prone to SQL-injection?!

I thought maybe the %s needs to be changed to %d where the datatype is decimal.
But then i get this error:

Exception has occurred: ValueError
unsupported format character 'd' (0x64) at index 37
  File "/home/hvn/intranet/intranet/Rekening/ing.py", line 87, in <module>
    cursor.execute('CALL controldubbel2(%s, %s, %s, %s, %d, %d, %s)', (datum2, naamtegen, tegenrekening, omschrijving1, bedrag, saldo, code))
ValueError: unsupported format character 'd' (0x64) at index 37

How to make the first codeline work?!
This is my psql-function:

CREATE OR REPLACE FUNCTION public.controldubbel2(_datum date, _naamtegen character varying,
_tegenrekening character varying, _omschrijving character varying,
_bedrag numeric, _saldo numeric, _code character varying)
 RETURNS TABLE(bestaat boolean)
 LANGUAGE plpgsql
AS $function$
BEGIN
    RETURN QUERY
    SELECT EXISTS (SELECT 1 FROM "rekening" WHERE "DATUM"=_datum
    AND "TEGENREKENING_IBAN_BBAN"=_tegenrekening AND
    "NAAM_TEGENPARTIJ"=_naamtegen AND "Omschrijving_1"=_omschrijving AND
    "BEDRAG"=_bedrag AND "saldo"=_saldo AND "CODE"=_code) as bestaat
LIMIT 1;
END
$function$

Thnx in advanced!

Asked By: HzM74

||

Answers:

the problem was in the fact that i was calling the procedures / functions wrongly:
This solved it for me:

Using a function:

cursor.execute(f"SELECT controldubbel2('{datum2}', '{naam}'), (datum, naamtegen))

Calling a procedure:

cursor.execute('CALL insertexcel(%s, %s)', (var1, var2))
Answered By: HzM74
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.