psycopg connection context manager drops X-Ray tracing wrapper, so cursor execute calls are not traced
- Dominant language
- Python
- Stars
- 338
- Forks
- 147
- PR merge metrics
- No merged PRs in 30d
Description
I am seeing a gap in the psycopg integration for aws-xray-sdk.
When patching psycopg succeeds, `psycopg.connect()` returns an `XRayTracedConn` proxy as expected. However, if the connection is used as a context manager with `with conn as c:`, the object returned from enter is the raw psycopg `Connection`, not the X-Ray wrapper. As a result, `c.cursor(...)` returns a raw psycopg Cursor, and `execute()` calls do not produce X-Ray subsegments.
### Observed behavior
`patch(("psycopg",), raise_errors=True) `succeeds
`psycopg.connect()` returns `aws_xray_sdk.ext.dbapi2.XRayTracedConn`
entering the connection context manager unwraps the proxy
`cursor()` on that entered object returns `psycopg.Cursor`
`execute()` on the cursor is not traced
if I create an explicit subsegment manually, that subsegment appears in X-Ray, which confirms the request has a valid segment and the DB code path is running
### Expected behavior
The psycopg X-Ray wrapper should preserve tracing across the connection context manager
`with conn as c:` should still return a wrapped connection, or otherwise ensure cursors created from the entered object are still traced
`execute()` should generate the native DB subsegment without needing manual instrumentation
### Reproduction
Install aws-xray-sdk 2.15.0
Install psycopg 3.3.4 and psycopg-pool 3.2.7
Call patch(("psycopg",), raise_errors=True)
Call psycopg.connect(...)
Use the connection in a with block
Create a cursor and execute a query
Observe that the cursor is raw psycopg.Cursor and no DB subsegment is emitted
### Environment details
aws-xray-sdk 2.15.0
psycopg 3.3.4
psycopg-pool 3.2.7
Python 3.12
Running in AWS Lambda
Contributor guide
Research direction
Start with the psycopg integration around patch() and XRayTracedConn, then reproduce the with conn as c: flow described in the issue. Done means the entered connection remains wrapped, its cursor is traced, and execute() produces the native database subsegment without manual instrumentation.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- aws, python
- Domain
- observability
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100