Thread: plpythonu: how to catch plpy.execute() exceptions

plpythonu: how to catch plpy.execute() exceptions

From
Dragos Valentin Moinescu
Date:
Hello all,

I am trying to create a plpythonu function that will execute some SQLs
stored in a table (because it should work much faster than executing
from remote).

The thing is that I cannot catch the exception raised by plpy.execute().

I tried this with the following code:

CREATE OR REPLACE FUNCTION __syncpg_execute() RETURNS boolean
AS $$
        try:
                plpy.execute("SELECT * FROM not_existing_table", 5)
        except Exception, exc:
                plpy.notice("Exception %s" % str(exc) )
        return True
$$ LANGUAGE plpythonu;

The result is:
# select __syncpg_execute();
WARNING:  PL/Python: plpy.SPIError: unrecognized error in PLy_spi_execute_query
CONTEXT:  PL/Python function "__syncpg_execute"
NOTICE:  Exception error return without exception set
CONTEXT:  PL/Python function "__syncpg_execute"
ERROR:  relation "not_existing_table" does not exist
LINE 1: SELECT * FROM not_existing_table
                                      ^
QUERY:  SELECT * FROM not_existing_table
CONTEXT:  PL/Python function "__syncpg_execute"

I am using Postgresql9.0 with python 2.4.3

Thank you

--
Best regards,
Dragos Moinescu

Re: plpythonu: how to catch plpy.execute() exceptions

From
Sergey Konoplev
Date:
Hi,

On 29 October 2010 17:02, Dragos Valentin Moinescu
<dragos.moinescu@gmail.com> wrote:
> The thing is that I cannot catch the exception raised by plpy.execute().

I came to this plpython function template. It handles errors properly
and works faster then usual function because of the code caching.

CREATE OR REPLACE FUNCTION some_plpython_function()
 RETURNS integer
 LANGUAGE plpythonu
AS $function$
""" Exaple of function's core cache and error handling """

sdNamespace = 'some_plpython_function'

if sdNamespace not in SD:

    def main():
        """ The function is assumed to be cached in SD and reused """

        result = None

        # Do whatever you need here

        return result

    # Cache body in SD
    SD[sdNamespace] = main

try:
    return SD[sdNamespace]()
except Exception, e:
    import traceback
    plpy.info(traceback.format_exc())

$function$;


>
> I tried this with the following code:
>
> CREATE OR REPLACE FUNCTION __syncpg_execute() RETURNS boolean
> AS $$
>        try:
>                plpy.execute("SELECT * FROM not_existing_table", 5)
>        except Exception, exc:
>                plpy.notice("Exception %s" % str(exc) )
>        return True
> $$ LANGUAGE plpythonu;
>
> The result is:
> # select __syncpg_execute();
> WARNING:  PL/Python: plpy.SPIError: unrecognized error in PLy_spi_execute_query
> CONTEXT:  PL/Python function "__syncpg_execute"
> NOTICE:  Exception error return without exception set
> CONTEXT:  PL/Python function "__syncpg_execute"
> ERROR:  relation "not_existing_table" does not exist
> LINE 1: SELECT * FROM not_existing_table
>                                      ^
> QUERY:  SELECT * FROM not_existing_table
> CONTEXT:  PL/Python function "__syncpg_execute"
>
> I am using Postgresql9.0 with python 2.4.3
>
> Thank you
>
> --
> Best regards,
> Dragos Moinescu
>
> --
> Sent via pgsql-admin mailing list (pgsql-admin@postgresql.org)
> To make changes to your subscription:
> http://www.postgresql.org/mailpref/pgsql-admin
>



--
Sergey Konoplev

Blog: http://gray-hemp.blogspot.com /
Linkedin: http://ru.linkedin.com/in/grayhemp /
JID/GTalk: gray.ru@gmail.com / Skype: gray-hemp

Re: plpythonu: how to catch plpy.execute() exceptions

From
Tom Lane
Date:
Dragos Valentin Moinescu <dragos.moinescu@gmail.com> writes:
> The thing is that I cannot catch the exception raised by plpy.execute().

Yeah, plpython's error handling is fundamentally broken.  Somebody
needs to rewrite it to be more like the other PLs.  In the meantime,
I'd suggest using plperl, which has gotten a lot more love than
plpython ever did.

            regards, tom lane

Re: plpythonu: how to catch plpy.execute() exceptions

From
Tom Lane
Date:
Sergey Konoplev <gray.ru@gmail.com> writes:
> On 29 October 2010 17:02, Dragos Valentin Moinescu
> <dragos.moinescu@gmail.com> wrote:
>> The thing is that I cannot catch the exception raised by plpy.execute().

> I came to this plpython function template. It handles errors properly
> and works faster then usual function because of the code caching.

Really?  As far as I can see, it's entirely impossible for a plpython
function to trap and recover from an error in plpy.execute.  It can
continue to run plain python code, but it won't be allowed to call
plpy.execute again, and the error will be rethrown when control exits
the function.  There's no way to fix that short of setting up
subtransactions, which is what the other PLs do.

            regards, tom lane

Re: plpythonu: how to catch plpy.execute() exceptions

From
Sergey Konoplev
Date:
On 29 October 2010 18:40, Tom Lane <tgl@sss.pgh.pa.us> wrote:
> Sergey Konoplev <gray.ru@gmail.com> writes:
>> On 29 October 2010 17:02, Dragos Valentin Moinescu
>> <dragos.moinescu@gmail.com> wrote:
>>> The thing is that I cannot catch the exception raised by plpy.execute().
>
>> I came to this plpython function template. It handles errors properly
>> and works faster then usual function because of the code caching.
>
> Really?  As far as I can see, it's entirely impossible for a plpython
> function to trap and recover from an error in plpy.execute.  It can
> continue to run plain python code, but it won't be allowed to call
> plpy.execute again, and the error will be rethrown when control exits
> the function.  There's no way to fix that short of setting up
> subtransactions, which is what the other PLs do.

Oh I am sorry for bothering you and other members. I have not read the
problem properly - my fault.

>
>                        regards, tom lane
>



--
Sergey Konoplev

Blog: http://gray-hemp.blogspot.com /
Linkedin: http://ru.linkedin.com/in/grayhemp /
JID/GTalk: gray.ru@gmail.com / Skype: gray-hemp

Re: plpythonu: how to catch plpy.execute() exceptions

From
"Joshua D. Drake"
Date:
On Fri, 2010-10-29 at 10:03 -0400, Tom Lane wrote:
> Dragos Valentin Moinescu <dragos.moinescu@gmail.com> writes:
> > The thing is that I cannot catch the exception raised by plpy.execute().
>
> Yeah, plpython's error handling is fundamentally broken.  Somebody
> needs to rewrite it to be more like the other PLs.  In the meantime,
> I'd suggest using plperl, which has gotten a lot more love than
> plpython ever did.

Or take a look at pg-python:

http://pgfoundry.org/projects/python/

Which is much more actively maintained and still Python.

JD

--
PostgreSQL.org Major Contributor
Command Prompt, Inc: http://www.commandprompt.com/ - 509.416.6579
Consulting, Training, Support, Custom Development, Engineering
http://twitter.com/cmdpromptinc | http://identi.ca/commandprompt