I'm having problems with trying to catch an error. I'm using Pyramid/SQLAlchemy and made a sign up form with email as the primary key. The problem is when a duplicate email is entered it raises a IntegrityError, so I'm trying to catch that error and provide a message but no matter what I do I can't catch it, the error keeps appearing.
new_user = Users(email, firstname, lastname, password)
return HTTPFound(location = request.route_url('new'))
message1 = "Yikes! Your email already exists in our system. Did you forget your password?"
In Pyramid, if you've configured your session (which the scaffold does for you automatically) to use the
ZopeTransactionExtension, then session is not flushed/committed until after the view has executed. If you want to catch any SQL errors yourself in your view, you need to force a
flush to send the SQL to the engine.
DBSession.flush() should do it after the
I'm updating this answer with an example of a savepoint just because there are very few examples around of how to do this with the transaction package.
def create_unique_object(db, max_attempts=3): while True: sp = transaction.savepoint() try: obj = MyObject() obj.identifier = uuid.uuid4().hex db.add(obj) db.flush() except IntegrityError: sp.rollback() max_attempts -= 1 if max_attempts < 1: raise else: return obj obj = create_unique_object(DBSession)
Note that even this is susceptible to duplicates between transactions if no table-level locking is used, but it at least shows how to use a savepoint.