Обсуждение: plpythonu: how to catch plpy.execute() exceptions
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
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
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
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
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
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