Thanks guys, great stuff Stuart, explanation and code. Although I have decide to check if the user exists first in the case I mentioned, I have other places where I can use this.
Stuart Bishop wrote: > akira wrote: > >> Hi all! >> >> I am trying to handle exceptions returned from the DB API. For example, >> I have a UNIQUE constraint on a field, when I try to save an object that >> violates this I get this: >> >> "duplicate key violates unique constraint" >> >> So trying to handle the errors properly so that I can return the right >> error to the user I have done some testing: >> >> try: >> store.add(user) >> store.flush() >> except Exception,e: >> print e.__class__.__name__ # this emits an >> "IntegrityError" >> print Exception.__str__(e) # this print s"duplicate >> key violates unique constraint "users_username_key'" >> >> if Exception.__str__(e) == 'duplicate key violates unique >> constraint "users_username_key': >> > > You appear to me missing a double quote here. > > When sniffing PostgreSQL exceptions, I always just use > str(e).startswith(...) or similar to match just a portion of the error > rather than the entire thing. Its still flakey in the face of localized > PostgreSQL installs and strings being changed across PG releases, but it is > the best we can do with psycopg1 as the driver (I vaguely recall psycopg2 > making it so we no longer need to sniff the strings). > > So... > > > try: > store.add(user) > store.flush() > except psycopg.IntegrityError, c: > if 'violates unique constraint' in str(e): > print "Username is already taken." > else: > raise > > >> Why does the first "if" conditional not work? Is this the right way to >> handle such a problem? Should I try to handle all the exceptions that >> might crop up? I am using postgresql, can I find all the defined >> Exceptional that I would like to handle there? >> > > I doubt you want to handle *all* of them: > http://www.postgresql.org/docs/8.2/static/errcodes-appendix.html > > I suspect you just want to catch all the integrity errors and return a human > readable string. Everything else is a programming or runtime error beyond > the user's control. This will also catch not null and foreign key > violations, which should never get as far as the DB. It also catches check > constraint violations, which *ideally* shouldn't (Our check constraints are > duplicated in Python on the app side, and the app side constraints are often > stricter than the db ones since there is less overhead in changing or > tweaking them. The DB constraints are really only there as a safety net). > > I haven't looked into how to use savepoints with Storm to avoid needing to > rollback the entire transaction if an integrity error is triggered, but it > should be simple enough if you always ROLLBACK TO SAVEPOINT <savepoint> on > failure and RELEASE SAVEPOINT <savepoint> on success, and only attempt a > single command within the savepoint, to avoid confusing Storm's caches. > > -- storm mailing list [email protected] Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/storm
