[DB-SIG] newbie question on trapping a DB error message using psycopg2 / DB-API

Andy Todd andy47 at halfcooked.com
Sat Oct 4 07:01:27 CEST 2008


Chris Wood wrote:
> If I run a python program that calls a stored procedure without a "try:" ,
> I see a descriptive message in the error that is returned (highlighted 
> in yellow below):
> 
>  >>> cur.execute("select * from f_test_return_error2('normon')")
> Traceback (most recent call last):
>   File "<stdin>", line 1, in ?
>   File "/usr/lib/python2.4/site-packages/psycopg2/extras.py", line 48, 
> in execute
>     return _cursor.execute(self, query, vars, async)
> psycopg2.ProgrammingError: Error.  Party name normon not found in the 
> party table.
> 
> but if I put the "cur.execute" in a "try:" / "except:" I cannot figure 
> out where to get the error text that I need,
> can anyone help please??
> 
> I know it is possible because a friend of mine can get it back from 
> SQLAlchemy and SQLAlchemy uses psycopg2.
> 
> thanks,
> - chris
> 
>

When asking questions on this list it is good practice to list which 
database you are using and which Python DB-API module you are using to 
access it.

In this case it looks like PostgreSQL and psycopg2.

However, I think the answer to your question lies in standard Python and 
I'd like to direct your attention to Chapter 8 of the Python tutorial 
(which can be found online here - 
http://www.python.org/doc/2.5.2/tut/node10.html), and in particular this 
extract from section 8.3:

"""
When an exception occurs, it may have an associated value, also known as 
the exception's argument. The presence and type of the argument depend 
on the exception type.

The except clause may specify a variable after the exception name (or 
tuple). The variable is bound to an exception instance with the 
arguments stored in instance.args. For convenience, the exception 
instance defines __getitem__ and __str__ so the arguments can be 
accessed or printed directly without having to reference .args.

But use of .args is discouraged. Instead, the preferred use is to pass a 
single argument to an exception (which can be a tuple if multiple 
arguments are needed) and have it bound to the message attribute. One 
may also instantiate an exception first before raising it and add any 
attributes to it as desired.

 >>> try:
...    raise Exception('spam', 'eggs')
... except Exception, inst:
...    print type(inst)     # the exception instance
...    print inst.args      # arguments stored in .args
...    print inst           # __str__ allows args to printed directly
...    x, y = inst          # __getitem__ allows args to be unpacked 
directly
...    print 'x =', x
...    print 'y =', y
...
<type 'exceptions.Exception'>
('spam', 'eggs')
('spam', 'eggs')
x = spam
y = eggs

If an exception has an argument, it is printed as the last part 
(`detail') of the message for unhandled exceptions.
"""

Which would lead to your code looking something like this:

 >>> try:
...     cur.execute("select * from f_test_return_error2('normon')")
... except ProgrammingError, msg:
...     print msg

Regards
Andy
-- 
 From the desk of Andrew J Todd esq - http://www.halfcooked.com/


More information about the DB-SIG mailing list