88 <a href="https://www.paypal.com/ncp/payment/6G9Z78QHUD4RJ"><img src="https://img.shields.io/badge/Donate-PayPal-brightgreen.svg?style=plastic" alt="Donate"/></a>
99 <a href="https://github.com/sponsors/ddc"><img src="https://img.shields.io/static/v1?style=plastic&label=Sponsor&message=%E2%9D%A4&logo=GitHub&color=ff69b4" alt="Sponsor"/></a>
1010 <br>
11+ <a href="https://github.com/psf/black"><img src="https://img.shields.io/badge/code%20style-black-000000.svg?style=plastic" alt="Code style: black"/></a>
1112 <a href="https://github.com/astral-sh/uv"><img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json?style=plastic" alt="uv"/></a>
1213 <a href="https://github.com/astral-sh/ruff"><img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json?style=plastic" alt="Ruff"/></a>
13- <a href="https://github.com/psf/black"><img src="https://img.shields.io/badge/code%20style-black-000000.svg?style=plastic" alt="Code style: black"/></a>
1414 <br>
1515 <a href="https://www.python.org/downloads"><img src="https://img.shields.io/pypi/pyversions/ddcDatabases.svg?style=plastic&logo=python&cacheSeconds=3600" alt="Python"/></a>
1616 <a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-yellow.svg?style=plastic" alt="License: MIT"/></a>
4949 - [ Available Methods] ( #available-methods )
5050- [ Logging] ( #logging )
5151- [ Development] ( #development )
52- - [ Create DEV Environment, Running Tests and Building Wheel] ( #create-dev-environment-running-tests-and-building-wheel )
52+ - [ Create DEV Environment and Running Tests] ( #create-dev-environment-and-running-tests )
53+ - [ Update DEV Environment Packages] ( #update-dev-environment-packages )
54+ - [ Building Wheel] ( #building-wheel )
5355 - [ Optionals] ( #optionals )
5456- [ License] ( #license )
5557- [ Support] ( #support )
@@ -91,8 +93,8 @@ Database classes use structured configuration dataclasses instead of flat keywor
9193| ------------------------------| ---------------------------------| -------------------------------------------------------------------------------------|
9294| ` {DB}PoolConfig ` | Connection pool settings | ` pool_size ` , ` max_overflow ` , ` pool_recycle ` , ` connection_timeout ` |
9395| ` {DB}SessionConfig ` | SQLAlchemy session settings | ` echo ` , ` autoflush ` , ` expire_on_commit ` , ` autocommit ` |
94- | ` {DB}ConnRetryConfig ` | Connection-level retry settings | ` enable_retry ` , ` max_retries ` , ` initial_retry_delay ` , ` max_retry_delay ` |
95- | ` {DB}OpRetryConfig ` | Operation-level retry settings | ` enable_retry ` , ` max_retries ` , ` initial_retry_delay ` , ` max_retry_delay ` , ` jitter ` |
96+ | ` {DB}ConnectionRetryConfig ` | Connection-level retry settings | ` enable_retry ` , ` max_retries ` , ` initial_retry_delay ` , ` max_retry_delay ` |
97+ | ` {DB}OperationRetryConfig ` | Operation-level retry settings | ` enable_retry ` , ` max_retries ` , ` initial_retry_delay ` , ` max_retry_delay ` , ` jitter ` |
9698| ` PersistentConnectionConfig ` | Persistent connection settings | ` idle_timeout ` , ` health_check_interval ` , ` auto_reconnect ` |
9799
98100** Note:** Replace ` {DB} ` with the database prefix: ` PostgreSQL ` , ` MySQL ` , ` MSSQL ` , ` Oracle ` , ` MongoDB ` , or ` Sqlite ` .
@@ -120,10 +122,10 @@ Retry with exponential backoff is enabled by default at two levels:
120122
121123** 1. Connection Level** - Retries when establishing database connections:
122124``` python
123- from ddcDatabases import PostgreSQL, PostgreSQLConnRetryConfig
125+ from ddcDatabases import PostgreSQL, PostgreSQLConnectionRetryConfig
124126
125127with PostgreSQL(
126- conn_retry_config = PostgreSQLConnRetryConfig (
128+ connection_retry_config = PostgreSQLConnectionRetryConfig (
127129 enable_retry = True , # Enable/disable retry (default: True)
128130 max_retries = 3 , # Maximum retry attempts (default: 3)
129131 initial_retry_delay = 1.0 , # Initial delay in seconds (default: 1.0)
@@ -136,10 +138,10 @@ with PostgreSQL(
136138
137139** 2. Operation Level** - Retries individual database operations (fetchall, insert, etc.):
138140``` python
139- from ddcDatabases import DBUtils, PostgreSQL, PostgreSQLOpRetryConfig
141+ from ddcDatabases import DBUtils, PostgreSQL, PostgreSQLOperationRetryConfig
140142
141143with PostgreSQL(
142- op_retry_config = PostgreSQLOpRetryConfig (
144+ operation_retry_config = PostgreSQLOperationRetryConfig (
143145 enable_retry = True , # Enable/disable (default: True)
144146 max_retries = 3 , # Max attempts (default: 3)
145147 initial_retry_delay = 1.0 , # Initial delay in seconds (default: 1.0)
@@ -174,6 +176,8 @@ from ddcDatabases import (
174176 MySQLPersistent,
175177 MongoDBPersistent,
176178 PersistentConnectionConfig,
179+ PostgreSQLConnectionRetryConfig,
180+ PostgreSQLOperationRetryConfig,
177181 close_all_persistent_connections,
178182)
179183
@@ -188,6 +192,19 @@ conn = PostgreSQLPersistent(
188192 health_check_interval = 30 , # seconds between health checks (default: 30)
189193 auto_reconnect = True , # auto-reconnect on failure (default: True)
190194 ),
195+ connection_retry_config = PostgreSQLConnectionRetryConfig(
196+ enable_retry = True , # enable connection retry (default: True)
197+ max_retries = 5 , # max connection attempts (default: 5)
198+ initial_retry_delay = 1.0 , # initial delay in seconds (default: 1.0)
199+ max_retry_delay = 30.0 , # max delay in seconds (default: 30.0)
200+ ),
201+ operation_retry_config = PostgreSQLOperationRetryConfig(
202+ enable_retry = True , # enable operation retry (default: True)
203+ max_retries = 3 , # max operation attempts (default: 3)
204+ initial_retry_delay = 0.5 , # initial delay in seconds (default: 0.5)
205+ max_retry_delay = 10.0 , # max delay in seconds (default: 10.0)
206+ jitter = 0.1 , # randomization factor (default: 0.1)
207+ ),
191208)
192209
193210# Use as context manager (doesn't disconnect on exit, just updates last-used time)
@@ -208,6 +225,36 @@ async with conn as session:
208225close_all_persistent_connections()
209226```
210227
228+ ### Execute with Retry
229+
230+ The ` execute_with_retry ` method provides automatic session management with retry logic:
231+
232+ ** Synchronous:**
233+ ``` python
234+ from ddcDatabases import PostgreSQLPersistent
235+
236+ db = PostgreSQLPersistent(logger = logger)
237+ result = db.execute_with_retry(
238+ lambda session : MyDal(session).do_something()
239+ )
240+ ```
241+
242+ ** Asynchronous:**
243+ ``` python
244+ from ddcDatabases import PostgreSQLPersistent
245+
246+ db = PostgreSQLPersistent(async_mode = True , logger = logger)
247+ result = await db.execute_with_retry(
248+ lambda session : MyDal(session).do_something()
249+ )
250+ ```
251+
252+ The method automatically:
253+ - Connects (or reuses existing connection)
254+ - Executes the operation with the session
255+ - Commits on success, rolls back on failure
256+ - Retries with exponential backoff if ` auto_reconnect ` is enabled
257+
211258** Available Persistent Connection Classes:**
212259
213260- ` PostgreSQLPersistent ` - PostgreSQL (sync/async)
@@ -605,7 +652,7 @@ async with PostgreSQL() as session:
605652 results = await db_utils_async.fetchall(stmt)
606653```
607654
608- ** Note:** Retry logic is configured at the database connection level using ` op_retry_config ` (see [ Retry Logic] ( #retry-logic ) section).
655+ ** Note:** Retry logic is configured at the database connection level using ` operation_retry_config ` (see [ Retry Logic] ( #retry-logic ) section).
609656
610657
611658# Logging
@@ -638,27 +685,41 @@ logging.getLogger("ddcDatabases").addHandler(logging.StreamHandler())
638685
639686# Development
640687
641- Must have [ UV] ( https://uv.run/docs/getting-started/installation ) ,
642- [ Black] ( https://black.readthedocs.io/en/stable/getting_started.html ) ,
643- [ Ruff] ( https://docs.astral.sh/ruff/installation/ ) , and
644- [ Poe the Poet] ( https://poethepoet.naber.dev/installation ) installed.
688+ Must have [ UV] ( https://uv.run/docs/getting-started/installation ) installed.
689+
690+ ## Create DEV Environment and Running Tests
645691
646- ## Create DEV Environment, Running Tests and Building Wheel
692+ > ** Note: ** All poe tasks automatically run ruff linter along with Black formatting
647693
648694``` shell
649- uv sync --all-extras
650- poe linter
695+ uv sync --all-extras --all-groups
651696poe test
652697poe test-integration
698+ ```
699+
700+ ## Update DEV Environment Packages
701+ This will update all packages dependencies
702+
703+ ``` shell
704+ poe updatedev
705+ ```
706+
707+
708+ ## Building Wheel
709+ This will update all packages, run linter, both unit and integration tests and finally build the wheel
710+
711+ ``` shell
653712poe build
654713```
655714
656715## Optionals
657716
658717``` shell
659- poe profile (create a cprofile_unit.prof file from unit tests)
660- poe profile-integration (create a cprofile_integration.prof file from integration tests)
661- ```
718+ # create a cprofile_unit.prof file from unit tests
719+ poe profile
720+ # create a cprofile_integration.prof file from integration tests
721+ poe profile-integration
722+ `````
662723
663724
664725# License
0 commit comments