-
-
Notifications
You must be signed in to change notification settings - Fork 8
Open
Labels
bugSomething isn't workingSomething isn't working
Description
Description
In certain use cases, driver exceptions can leak past the SQLSpec exception handling. This seems to only occur when the compiled package is used. When pure-python is used because the .so is missing, exceptions are caught as expected.
URL to code causing the issue
No response
MCVE
import asyncio
import importlib.util
import platform
import sys
import asyncpg
import sqlspec
import sqlspec.exceptions
from sqlspec.adapters.asyncpg import AsyncpgConfig
DSN = "postgresql://postgress:password@localhost:5432/test"
async def main() -> None:
spec = importlib.util.find_spec("sqlspec.driver._async")
origin = spec.origin if spec else "?"
compiled = origin.endswith(".so") or origin.endswith(".pyd")
print(f"Python {platform.python_version()}, sqlspec {sqlspec.__version__}, asyncpg {asyncpg.__version__}")
print(f"driver._async: {'compiled' if compiled else 'pure Python'} ({origin})\n")
config = AsyncpgConfig(connection_config={"dsn": DSN}, pool_config={"min_size": 1, "max_size": 2})
await config.create_pool()
try:
async with config.provide_session() as s:
await s.execute(
"DROP TABLE IF EXISTS child; DROP TABLE IF EXISTS parent;"
"CREATE TABLE parent (id serial PRIMARY KEY);"
"CREATE TABLE child (id serial PRIMARY KEY, parent_id int NOT NULL REFERENCES parent(id));"
"INSERT INTO parent VALUES (1); INSERT INTO child VALUES (1, 1);"
)
async with config.provide_session() as s:
try:
await s.execute("DELETE FROM parent WHERE id = $1", 1)
print("ERROR: no exception raised")
sys.exit(2)
except sqlspec.exceptions.ForeignKeyViolationError:
print("PASS: caught sqlspec.exceptions.ForeignKeyViolationError")
except asyncpg.exceptions.ForeignKeyViolationError:
print("FAIL: caught raw asyncpg.exceptions.ForeignKeyViolationError")
print(" exception was not mapped by dispatch_statement_execution")
sys.exit(1)
finally:
async with config.provide_session() as s:
await s.execute("DROP TABLE IF EXISTS child; DROP TABLE IF EXISTS parent;")
await config.close_pool()
if __name__ == "__main__":
asyncio.run(main())Steps to reproduce
1. Run MCVE with a fresh Python environment - should pass through the asyncpg error.
2. Rename the `_async.cpython-313-x86_64-linux-gnu.so` file to force pure python
3. Run MCVE again, SQLSpec exception should propagateScreenshots
No response
Logs
When using SQLSpec as installed:
❯ uv run mcve_sqlspec_bug/reproduce.py
Python 3.13.9, sqlspec 0.38.4, asyncpg 0.31.0
driver._async: compiled (.../.venv/lib/python3.13/site-packages/sqlspec/driver/_async.cpython-313-x86_64-linux-gnu.so)
FAIL: caught raw asyncpg.exceptions.ForeignKeyViolationError
exception was not mapped by dispatch_statement_execution
After renaming `_async.cpython-313-x86_64-linux-gnu.so`:
❯ uv run mcve_sqlspec_bug/reproduce.py
Python 3.13.9, sqlspec 0.38.4, asyncpg 0.31.0
driver._async: pure Python (/home/jordan/Projects/athenaeum_core/.venv/lib/python3.13/site-packages/sqlspec/driver/_async.py)
PASS: caught sqlspec.exceptions.ForeignKeyViolationErrorPackage Version
0.38.4
Platform
- Linux
- Mac
- Windows
- Other (Please specify in the description above)
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working