feat(sqlalchemy): Support span streaming #6132
7 issues
High
StreamedSpan lacks set_data method called in _wrap_cursor_creation - `sentry_sdk/integrations/asyncpg.py:105`
The type annotation change to Iterator[Union[Span, StreamedSpan]] reflects that record_sql_queries can return either type, but line 156 calls span.set_data("db.cursor", res) which will fail with AttributeError when span streaming is enabled. StreamedSpan only has set_attribute(), not set_data(). This causes a runtime crash when using asyncpg cursor operations with span streaming enabled.
Also found at:
sentry_sdk/integrations/asyncpg.py:201-205
Medium
Potential runtime error if no root span found in streamed spans - `tests/conftest.py:508`
When root_span=None (streamed spans mode), the code expects to find a span without parent_span_id in the spans list. If no such span exists (e.g., all spans have a parent_span_id), root_span remains None and render_span(root_span) at line 508 will attempt to access span["attributes"] on None, raising a TypeError. This is a potential edge case that could cause confusing test failures.
Low
Debug print statement left in test fixture - `tests/conftest.py:486`
A print(span) statement at line 486 appears to be debugging code that was accidentally left in the fixture. This will pollute test output with span data on every test run that uses this fixture, making it harder to identify actual test failures and increasing noise in CI logs.
Missing SERVER_ADDRESS assertion in span_streaming branch - `tests/integrations/sqlalchemy/test_sqlalchemy.py:293`
The span_streaming branch asserts that SPANDATA.SERVER_PORT is not in span['attributes'] but omits the SPANDATA.SERVER_ADDRESS assertion that exists in the else branch (line 314). This creates inconsistent test coverage between the two code paths - the non-streaming path verifies that SERVER_ADDRESS is absent when engine.url is None, but the streaming path does not.
Also found at:
tests/integrations/sqlalchemy/test_sqlalchemy.py:162
Dead code: span_streaming check always False in else branch - `tests/integrations/sqlalchemy/test_sqlalchemy.py:989-990`
In the else branch (line 962+), the code path is only executed when span_streaming is False. However, the fake_record_sql_queries class defined inside this branch (lines 984-994) still contains a conditional if span_streaming: check that will never be True. This dead code branch (lines 989-990) can never execute, making the conditional unnecessary. While not a runtime error, this indicates the test was likely duplicated from the streaming branch without proper cleanup.
Debug print statement left in test fixture - `tests/conftest.py:486`
A print(span) statement on line 486 was left in the code, likely from debugging during development. This will pollute test output with span data for every span processed by render_span_tree(), making test logs noisy and harder to read.
Missing SERVER_ADDRESS assertion in span_streaming=True branch of test_transactions - `tests/integrations/sqlalchemy/test_sqlalchemy.py:162`
In the test_transactions function, the span_streaming=True branch (line 162) only asserts that SPANDATA.SERVER_PORT not in span["attributes"], while the span_streaming=False branch (lines 203-204) asserts both SPANDATA.SERVER_ADDRESS not in span["data"] and SPANDATA.SERVER_PORT not in span["data"]. This inconsistency means the span streaming path has less test coverage and could miss regressions where SERVER_ADDRESS is incorrectly set for in-memory SQLite databases.
Also found at:
tests/integrations/sqlalchemy/test_sqlalchemy.py:293
4 skills analyzed
| Skill | Findings | Duration | Cost |
|---|---|---|---|
| code-review | 4 | 12m 59s | $5.36 |
| find-bugs | 3 | 9m 29s | $10.56 |
| skill-scanner | 0 | 11m 31s | $1.09 |
| security-review | 0 | 12m 52s | $1.48 |
Duration: 46m 52s · Tokens: 12.8M in / 144.1k out · Cost: $18.52 (+extraction: $0.02, +merge: $0.00, +fix_gate: $0.01, +dedup: $0.01)