1

I am using Python and psycopg2.

I am attempting to execute a prepared statement with a list of values as such:

cur.callproc(prepared_func, prepared_values)

psycopg2.DataError: invalid input syntax for integer: "WwLEA6XZ0V"
LINE 1: ... fn_approve_external_lead(ARRAY[1004, 2, 1079412, 'WwLEA6XZ0...

The function in Postgres looks as follows:

CREATE OR REPLACE FUNCTION fn_approve_external_lead(
     internal_usrid bigint
   , ofr_src_id bigint
   , ofr_ext_id varchar
   , puuid varchar
   , paid varchar
   , p_note varchar DEFAULT '') ...

So as far as I can tell I am putting a non-int value into a non-int argument, so it should work, but for some reason it thinks this value is an int?

What would cause this?

6
  • do other records go through except this one? also what happens when the datatype is text instead of varchar? Commented Dec 22, 2017 at 18:36
  • No this is the first record so presumably they all fail Commented Dec 22, 2017 at 18:38
  • Please show the rest of the code. How are prepared_func and prepared_values defined in Python? Commented Dec 22, 2017 at 18:42
  • Can you try specifying the varchar length. I have read that if you don't specify it is set to some default length of characters. Commented Dec 22, 2017 at 18:43
  • prepared_func is a string and prepared_values is a list. I’ll post the actual data in a bit, away from computer now Commented Dec 22, 2017 at 18:45

1 Answer 1

2

Your input fails with a syntax error in the ARRAY constructor before you even get to function type resolution - where you will get more error messages due to other type mismatches once you remove the ARRAY constructor that shouldn't be in the call at all.

Your solution is to pass separate parameters of matching type, not an array. The rest is just explanation of what we saw.

What really happened

An array can only include values of the same type, but your input mixes numeric constants with a non-numeric string literal, which cannot be resolved.

If you want it to resolve to text[] (array of text), you have to provide string literals like so:

SELECT ARRAY['1004', '2', '1079412', 'WwLEA6XZ0'];

Or an array literal directly, like so:

SELECT '{1004, 2, 1079412, WwLEA6XZ0}'::text[];

But once you start an ARRAY constructor with numeric constants, only numeric types are legal to add. Or at least string literals with content that can be coerced to the same type. You could:

SELECT ARRAY[1004, 2, 1079412, '1'];

... resulting in int[]. Or:

SELECT ARRAY[1004, 2, 1079412, 1.0];

Or even:

SELECT ARRAY[1004, 2, 1079412.0, '1.0'];

... both resulting in numeric[].

But ARRAY[1004, 2, 1079412, 'WwLEA6XZ0V'] is illegal and rightfully so.

The exact rules of type resolution for array constructors can be found in this chapter of the manual: "Type Conversion" - "UNION, CASE, and Related Constructs". You journey ends at:

  1. Convert all inputs to the selected type. Fail if there is not a conversion from a given input to the selected type.

Since the string literal 'WwLEA6XZ0V' cannot be converted to integer.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.