Unable to get retry working with unique constraint failure. #313
I haven't been able to figure out how to get the retry parameter to work correctly with database errors. I can reproduce the test code with ZeroDivisionError exceptions, but not with database errors (such as a unique constraint violation).
#!/usr/bin/env python3 from pony import orm db = orm.Database() class Foo(db.Entity): unique = orm.Required(int, unique=True) @orm.db_session(retry=3) def retry_unique(): print("RETRY_UNIQUE") Foo(unique=1) @orm.db_session(retry=3, retry_exceptions=[ZeroDivisionError]) def retry_zero_div(): print("RETRY_ZERO_DIV") 1/0 def main(): db.bind(provider='postgres', user='postgres', password='password', host='127.0.0.1', database='test_retry') db.generate_mapping(create_tables=True) try: # This will run 4 times. retry_zero_div() except: pass try: # This will succeed (if db is empty). retry_unique() # This will only run once. <- Bug? retry_unique() except: pass if __name__ == '__main__': main()
Running this code on a clean database produces the following output:
I (correctly) see
When I trace
At this point, I'm not entirely sure if I'm doing something wrong or there is really a bug. Any advice would be appreciated.
The text was updated successfully, but these errors were encountered:
Thanks for reporting! It was a bug.
Previous code for retry handling assumed that exception is raised inside a function. In your example, the exception was raised outside of the function, when
# Major features * Hybrid methods and properties added: https://docs.ponyorm.com/entities.html#hybrid-methods-and-properties * Allow to base queries on another queries: `select(x.a for x in prev_query if x.b)` * Added support of Python 3.7 * Added support of PyPy * `group_concat()` aggregate function added * pony.flask subpackage added for integration with Flask # Other features * `distinct` option added to aggregate functions * Support of explicit casting to `float` and `bool` in queries # Improvements * Apply @cut_traceback decorator only when pony.MODE is 'INTERACTIVE' # Bugfixes * In SQLite3 `LIKE` is case sensitive now * #249: Fix incorrect mixin used for Timedelta * #251: correct dealing with qualified table names * #301: Fix aggregation over JSON Column * #306: Support of frozenset constants added * #308: Fixed an error when assigning JSON attribute value to the same attribute: obj.json_attr = obj.json_attr * #313: Fix missed retry on exception raised during db_session.__exit__ * #314: Fix AttributeError: 'NoneType' object has no attribute 'seeds' * #315: Fix attribute lifting for JSON attributes * #321: Fix KeyError on obj.delete() * #325: duplicating percentage sign in raw SQL queries without parameters * #331: Overriding __len__ in entity fails * #336: entity declaration serialization * #357: reconnect after PostgreSQL server closed the connection unexpectedly * Fix Python implementation of between() function and rename arguments: between(a, x, y) -> between(x, a, b) * Fix retry handling: in PostgreSQL and Oracle an error can be raised during commit * Fix optimistic update checks for composite foreign keys * Don't raise OptimisticCheckError if db_session is not optimistic * Handling incorrect datetime values in MySQL * Improved ImportError exception messages when MySQLdb, pymysql, psycopg2 or psycopg2cffi driver was not found * desc() function fixed to allow reverse its effect by calling desc(desc(x)) * __contains__ method should check if objects belong to the same db_session * Fix pony.MODE detection; mod_wsgi detection according to official doc * A lot of inner fixes