diff --git a/CHANGELOG.md b/CHANGELOG.md index 28a86604..90ca4118 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# PonyORM release 0.7.17 (2023-06-15) + +* Introduce retry_delay into retry db_session + # PonyORM release 0.7.16 (2022-01-28) ## Bugfixes diff --git a/README.md b/README.md index 3b63b61a..2058d7b1 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,9 @@ Pony is an advanced object-relational mapper. The most interesting feature of Po Here is an example query in Pony: - select(p for p in Product if p.name.startswith('A') and p.cost <= 1000) +```python +select(p for p in Product if p.name.startswith('A') and p.cost <= 1000) +``` Pony translates queries to SQL using a specific database dialect. Currently Pony works with SQLite, MySQL, PostgreSQL and Oracle databases. @@ -62,4 +64,4 @@ Meet the PonyORM team, chat with the community members, and get your questions a Join our newsletter at [ponyorm.org](https://ponyorm.org). Reach us on [Twitter](https://twitter.com/ponyorm). -Copyright (c) 2013-2022 Pony ORM. All rights reserved. info (at) ponyorm.org +Copyright (c) 2013-2023 Pony ORM. All rights reserved. info (at) ponyorm.org diff --git a/pony/__init__.py b/pony/__init__.py index 0201f2aa..536130f1 100644 --- a/pony/__init__.py +++ b/pony/__init__.py @@ -3,7 +3,7 @@ import os, sys from os.path import dirname -__version__ = '0.7.16' +__version__ = '0.7.17' def detect_mode(): try: import google.appengine diff --git a/pony/orm/core.py b/pony/orm/core.py index 845e672a..60514bfc 100644 --- a/pony/orm/core.py +++ b/pony/orm/core.py @@ -4,7 +4,7 @@ import builtins, json, re, sys, types, datetime, logging, itertools, warnings, inspect, ast from operator import attrgetter, itemgetter from itertools import chain, starmap, repeat -from time import time +from time import time, sleep from decimal import Decimal from random import shuffle, randint, random from threading import Lock, RLock, current_thread, _MainThread @@ -407,16 +407,20 @@ def rollback(): select_re = re.compile(r'\s*select\b', re.IGNORECASE) class DBSessionContextManager(object): - __slots__ = 'retry', 'retry_exceptions', 'allowed_exceptions', \ + __slots__ = 'retry', 'retry_delay', 'retry_exceptions', 'allowed_exceptions', \ 'immediate', 'ddl', 'serializable', 'strict', 'optimistic', \ 'sql_debug', 'show_values' - def __init__(db_session, retry=0, immediate=False, ddl=False, serializable=False, strict=False, optimistic=True, + def __init__(db_session, retry:int=0, retry_delay:int=0, immediate:bool=False, ddl:bool=False, serializable:bool=False, strict:bool=False, optimistic:bool=True, retry_exceptions=(TransactionError,), allowed_exceptions=(), sql_debug=None, show_values=None): if retry != 0: if type(retry) is not int: throw(TypeError, "'retry' parameter of db_session must be of integer type. Got: %s" % type(retry)) + if type(retry_delay) is not int: throw(TypeError, + "'retry_delay' parameter of db_session must be of integer type. Got: %s" % type(retry)) if retry < 0: throw(TypeError, "'retry' parameter of db_session must not be negative. Got: %d" % retry) + if retry_delay < 0: throw(TypeError, + "'retry_delay' parameter of db_session must not be negative. Got: %d" % retry) if ddl: throw(TypeError, "'ddl' and 'retry' parameters of db_session cannot be used together") if not callable(allowed_exceptions) and not callable(retry_exceptions): for e in allowed_exceptions: @@ -424,6 +428,7 @@ def __init__(db_session, retry=0, immediate=False, ddl=False, serializable=False 'The same exception %s cannot be specified in both ' 'allowed and retry exception lists simultaneously' % e.__name__) db_session.retry = retry + db_session.retry_delay = retry_delay db_session.ddl = ddl db_session.serializable = serializable db_session.immediate = immediate or ddl or serializable or not optimistic @@ -533,6 +538,7 @@ def new_func(func, *args, **kwargs): if not do_retry: raise rollback() + sleep(db_session.retry_delay) finally: db_session.__exit__(exc_type, exc, tb) reraise(exc_type, exc, tb)