feat(sqlalchemy): Support span streaming #6132
8 issues
High
Asyncpg integration will raise AttributeError when span streaming is enabled - `sentry_sdk/integrations/asyncpg.py:121`
The _record function now yields either a Span or StreamedSpan from record_sql_queries, but the callers (e.g., _wrap_connection_method at line 133) pass the span to _set_db_data which calls span.set_data(). The StreamedSpan class does not have a set_data method (only set_attribute), causing an AttributeError at runtime when span streaming mode is enabled. The PR description mentions Django and psycopg cannot be used with span streaming yet, but asyncpg has the same issue and is not mentioned.
Also found at:
sentry_sdk/integrations/django/__init__.py:644
Low
Debug print statement left in test fixture - `tests/conftest.py:486`
A print(span) statement on line 486 appears to be leftover debug code in the render_span_tree fixture. This will print span data to stdout during every test that uses this fixture, polluting test output and making CI logs harder to read.
Missing SERVER_ADDRESS assertion in span_streaming=True branch - `tests/integrations/sqlalchemy/test_sqlalchemy.py:162`
In test_transactions, the span_streaming=True branch only asserts that SPANDATA.SERVER_PORT is not in attributes (line 162), but the span_streaming=False branch asserts both SERVER_ADDRESS and SERVER_PORT are absent (lines 203-204). This inconsistency means the test won't catch regressions where SERVER_ADDRESS is incorrectly included in streamed spans.
Also found at:
tests/integrations/sqlalchemy/test_sqlalchemy.py:226-243
Test assumes span ordering which may be fragile in span_streaming mode - `tests/integrations/sqlalchemy/test_sqlalchemy.py:344-346`
In test_long_sql_query_preserved, the span_streaming branch accesses spans[0] directly without filtering by origin (line 344). Other similar tests in this file (e.g., test_transactions_no_engine_url at line 284-287) filter spans by sentry.origin == 'auto.db.sqlalchemy' first. If additional spans are captured or ordering changes, this test could fail or pass incorrectly.
Dead code in test: inner span_streaming check never true in else branch - `tests/integrations/sqlalchemy/test_sqlalchemy.py:989-994`
In test_no_query_source_if_duration_too_short, the inner if span_streaming: conditional at lines 989-991 is inside the outer else: block (line 962), where span_streaming is always False. The lines 989-991 are dead code that will never execute. This creates confusing test code with excessive branching, even though the test will functionally work correctly.
Incorrect type annotation in _handle_error allows StreamedSpan but declares only Span - `sentry_sdk/integrations/sqlalchemy.py:104`
At line 104, the type annotation declares span: "Optional[Span]" but the code at line 107 explicitly handles StreamedSpan instances via isinstance(span, StreamedSpan). This inconsistency could cause static type checkers to flag the isinstance check as always-false, and it misrepresents the actual runtime behavior where _sentry_sql_span can be either Span or StreamedSpan.
Also found at:
sentry_sdk/tracing_utils.py:178
Debug print statement left in test fixture - `tests/conftest.py:486`
A print(span) statement on line 486 appears to be debug code accidentally left in. This will pollute test output by printing every span object during test execution, making test logs noisy and harder to read.
Missing SERVER_ADDRESS assertion in span_streaming path of test_transactions - `tests/integrations/sqlalchemy/test_sqlalchemy.py:162`
The span_streaming path in test_transactions is missing the SPANDATA.SERVER_ADDRESS not in span["attributes"] assertion that exists in the non-streaming path (line 203). The non-streaming path validates both SERVER_ADDRESS and SERVER_PORT are absent from span data, but the streaming path only validates SERVER_PORT. This creates a gap in test coverage where the streaming implementation could incorrectly include SERVER_ADDRESS without test failure.
Also found at:
tests/integrations/sqlalchemy/test_sqlalchemy.py:289-293
4 skills analyzed
| Skill | Findings | Duration | Cost |
|---|---|---|---|
| code-review | 5 | 9m 20s | $5.46 |
| find-bugs | 3 | 9m 41s | $10.75 |
| skill-scanner | 0 | 11m 35s | $1.55 |
| security-review | 0 | 9m 37s | $1.56 |
Duration: 40m 12s · Tokens: 13.3M in / 125.9k out · Cost: $19.37 (+extraction: $0.02, +merge: $0.01, +fix_gate: $0.02, +dedup: $0.01)