Skip to content

Commit 10fa85f

Browse files
authored
Merge pull request #6 from TechPrismatica/fix/raw_db
fix: 🐛 Raw db session requirement if tenant id is passed
2 parents 14e3c00 + 98e3b49 commit 10fa85f

File tree

6 files changed

+518
-12
lines changed

6 files changed

+518
-12
lines changed

.github/copilot-instructions.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,15 @@ Always reference these instructions first and fallback to search or bash command
4343
python -c "
4444
from sql_db_utils import SQLSessionManager
4545
manager = SQLSessionManager()
46-
46+
4747
@manager.register_precreate('test_db')
4848
def test_precreate(tenant_id):
4949
return 'SELECT 1;'
50-
50+
5151
@manager.register_postcreate('test_db')
5252
def test_postcreate(tenant_id):
5353
return 'SELECT 2;'
54-
54+
5555
print('Precreate/Postcreate registration successful')
5656
"
5757
```
@@ -117,7 +117,7 @@ sql-db-utils/
117117
### Development Dependencies:
118118
- **Testing**: pytest, pytest-cov, coverage
119119
- **Linting**: ruff (replaces black, flake8, isort)
120-
- **Git hooks**: pre-commit
120+
- **Git hooks**: pre-commit
121121
- **Type checking**: Built into package development
122122
- **Core Dependencies**: SQLAlchemy, sqlalchemy-utils, psycopg, python-dateutil, whenever
123123

@@ -221,4 +221,4 @@ sql-db-utils/
221221
- Changes to sync version should be mirrored in async version
222222
- Test both implementations when making session management changes
223223
- Verify async patterns use proper `await` keywords
224-
- Check that both versions handle errors consistently
224+
- Check that both versions handle errors consistently

.pre-commit-config.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
repos:
22
- repo: https://github.com/pre-commit/pre-commit-hooks
3-
rev: v5.0.0
3+
rev: v6.0.0
44
hooks:
55
- id: end-of-file-fixer
66
- id: trailing-whitespace
77
- id: requirements-txt-fixer
88
- repo: https://github.com/charliermarsh/ruff-pre-commit
9-
rev: v0.11.0
9+
rev: v0.14.4
1010
hooks:
1111
- id: ruff
1212
args:

sql_db_utils/__version__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "1.3.1"
1+
__version__ = "1.3.2"

sql_db_utils/asyncio/session_management.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,11 +121,27 @@ async def get_engine_obj(
121121
) -> AsyncEngine:
122122
return await self._get_engine(database=database, tenant_id=tenant_id, metadata=metadata)
123123

124-
def get_db_factory(self, database: str, retrying: bool = False) -> AsyncGenerator[AsyncSession, Any]:
124+
def get_db_factory(
125+
self, database: str, retrying: bool = False, raw_db: bool = False
126+
) -> AsyncGenerator[AsyncSession, Any]:
127+
"""
128+
Create a database session factory for FastAPI dependency injection.
129+
130+
Args:
131+
database: Name of the database.
132+
retrying: Whether to enable retry logic for queries.
133+
raw_db: If True, bypasses tenant_id and creates a system-level session without tenant isolation.
134+
Use with caution for admin operations, migrations, or other system-level tasks.
135+
WARNING: Bypassing tenant isolation may expose all data in the database to the session.
136+
Only use raw_db=True for trusted, internal operations.
137+
138+
Returns:
139+
An async factory function that yields database sessions.
140+
"""
125141
from fastapi import Cookie
126142

127143
async def get_db(tenant_id: Annotated[Union[str, None], Cookie()] = None) -> AsyncGenerator[AsyncSession, Any]:
128-
yield await self.get_session(database=database, tenant_id=tenant_id, retrying=retrying)
144+
yield await self.get_session(database=database, tenant_id=None if raw_db else tenant_id, retrying=retrying)
129145

130146
return get_db
131147

sql_db_utils/session_management.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,11 +121,24 @@ def get_engine_obj(
121121
) -> Engine:
122122
return self._get_engine(database=database, tenant_id=tenant_id, metadata=metadata)
123123

124-
def get_db_factory(self, database: str, retrying: bool = False) -> Callable:
124+
def get_db_factory(self, database: str, retrying: bool = False, raw_db: bool = False) -> Callable:
125+
"""
126+
Create a database session factory for FastAPI dependency injection.
127+
128+
Args:
129+
database (str): Name of the database.
130+
retrying (bool): Whether to enable retry logic for queries.
131+
raw_db (bool): If True, bypasses tenant_id and creates a system-level session without tenant isolation.
132+
Use with caution for admin operations, migrations, or other system-level tasks.
133+
WARNING: Bypassing tenant isolation may expose all data and should only be used by trusted code.
134+
135+
Returns:
136+
Callable: A factory function that yields database sessions.
137+
"""
125138
from fastapi import Cookie
126139

127140
def get_db(tenant_id: Annotated[str, Cookie()] = None) -> Session:
128-
yield self.get_session(database=database, tenant_id=tenant_id, retrying=retrying)
141+
yield self.get_session(database=database, tenant_id=None if raw_db else tenant_id, retrying=retrying)
129142

130143
return get_db
131144

0 commit comments

Comments
 (0)