From 474a42473adf9b18417242f1fc0691a857ec578b Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Mon, 28 Feb 2011 18:41:10 +0200 Subject: PL/Python custom SPI exceptions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This provides a separate exception class for each error code that the backend defines, as well as the ability to get the SQLSTATE from the exception object. Jan UrbaƄski, reviewed by Steve Singer --- doc/src/sgml/plpython.sgml | 49 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) (limited to 'doc/src') diff --git a/doc/src/sgml/plpython.sgml b/doc/src/sgml/plpython.sgml index 73203e62512..a729fa3e177 100644 --- a/doc/src/sgml/plpython.sgml +++ b/doc/src/sgml/plpython.sgml @@ -962,7 +962,7 @@ $$ LANGUAGE plpythonu; Functions accessing the database might encounter errors, which will cause them to abort and raise an exception. Both plpy.execute and - plpy.prepare can raise an instance of + plpy.prepare can raise an instance of a subclass of plpy.SPIError, which by default will terminate the function. This error can be handled just like any other Python exception, by using the try/except @@ -978,6 +978,53 @@ CREATE FUNCTION try_adding_joe() RETURNS text AS $$ $$ LANGUAGE plpythonu; + + + The actual class of the exception being raised corresponds to the + specific condition that caused the error. Refer + to for a list of possible + conditions. The module + plpy.spiexceptions defines an exception class + for each PostgreSQL condition, deriving + their names from the condition name. For + instance, division_by_zero + becomes DivisionByZero, unique_violation + becomes UniqueViolation, fdw_error + becomes FdwError, and so on. Each of these + exception classes inherits from SPIError. This + separation makes it easier to handle specific errors, for + instance: + +CREATE FUNCTION insert_fraction(numerator int, denominator int) RETURNS text AS $$ +from plpy import spiexceptions +try: + plan = plpy.prepare("INSERT INTO fractions (frac) VALUES ($1 / $2)", ["int", "int"]) + plpy.execute(plan, [numerator, denominator]) +except spiexceptions.DivisionByZero: + return "denominator cannot equal zero" +except spiexceptions.UniqueViolation: + return "already have that fraction" +except plpy.SPIError, e: + return "other error, SQLSTATE %s" % e.sqlstate +else: + return "fraction inserted" +$$ LANGUAGE plpythonu; + + Note that because all exceptions from + the plpy.spiexceptions module inherit + from SPIError, an except + clause handling it will catch any database access error. + + + + As an alternative way of handling different error conditions, you + can catch the SPIError exception and determine + the specific error condition inside the except + block by looking at the sqlstate attribute of + the exception object. This attribute is a string value containing + the SQLSTATE error code. This approach provides + approximately the same functionality + -- cgit v1.2.3