Skip to content

feat(integrations): Add integration for aiomysql#4703

Open
tonal wants to merge 20 commits intogetsentry:masterfrom
tonal:patch-2
Open

feat(integrations): Add integration for aiomysql#4703
tonal wants to merge 20 commits intogetsentry:masterfrom
tonal:patch-2

Conversation

@tonal
Copy link
Copy Markdown

@tonal tonal commented Aug 14, 2025

Add support for aiomysql to the SDK.

@tonal tonal requested a review from a team as a code owner August 14, 2025 09:43
cursor[bot]

This comment was marked as outdated.

cursor[bot]

This comment was marked as outdated.

cursor[bot]

This comment was marked as outdated.

@antonpirker antonpirker added the New Integration Integrating with a new framework or library label Sep 11, 2025
@antonpirker antonpirker changed the title integration for aiomysql Feat(integrations): Add integration for aiomysql Sep 11, 2025
@antonpirker
Copy link
Copy Markdown
Contributor

Hey @tonal thanks for the PR, great work! Could you address the cursor comments above?

@antonpirker antonpirker changed the title Feat(integrations): Add integration for aiomysql feat(integrations): Add integration for aiomysql Sep 11, 2025
cursor[bot]

This comment was marked as outdated.

Comment on lines +2 to +4
"""
Adapted from module sentry_sdk.integrations.asyncpg
"""
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @tonal ,

Thanks for the contribution, much appreciated!

Can you add unit tests for the integration as well? You can probably adapt them from the asyncpg tests.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 12, 2026

Semver Impact of This PR

🟡 Minor (new features)

📋 Changelog Preview

This is how your changes will appear in the changelog.
Entries from this PR are highlighted with a left border (blockquote style).


New Features ✨

Integrations

  • Add integration for aiomysql by tonal in #4703
  • Instrument pyreqwest tracing by servusdei2018 in #5682

Other

  • (ai) Redact base64 data URLs in image_url content blocks by ericapisani in #5953
  • (ci) Cancel in-progress PR workflows on new commit push by joshuarli in #5994
  • (litellm) Add async callbacks by alexander-alderman-webb in #5969

Bug Fixes 🐛

Anthropic

  • Capture exceptions for stream() calls by alexander-alderman-webb in #5950
  • Stop setting transaction status when child span fails by alexander-alderman-webb in #5717
  • Only finish relevant spans in .create() patches by alexander-alderman-webb in #5716

Pydantic Ai

  • Adapt import for new library versions by alexander-alderman-webb in #5984
  • Use first-class hooks when available by alexander-alderman-webb in #5947

Other

  • (huggingface_hub) Stop setting transaction status when a child span fails by Zenithatic in #5952
  • (litellm) Avoid double span exits when streaming by alexander-alderman-webb in #5933
  • (wsgi) Respect HTTP_X_FORWARDED_PROTO in request.url construction by sl0thentr0py in #5963

Internal Changes 🔧

Litellm

  • Replace mocks with httpx types in rate-limit test by alexander-alderman-webb in #5975
  • Replace mocks with httpx types in embedding tests by alexander-alderman-webb in #5970
  • Replace mocks with httpx types in nonstreaming completion() tests by alexander-alderman-webb in #5937
  • Remove dead attributes by alexander-alderman-webb in #5985

Other

  • (ai) Remove gen_ai.tool.type span attribute by ericapisani in #5964
  • (anthropic) Separate sync and async .create() patches by alexander-alderman-webb in #5715
  • (openai) Split token counting by API for easier deprecation by ericapisani in #5930
  • (openai-agents) Remove error attributes by alexander-alderman-webb in #5986
  • (opentelemetry) Ignore mypy error by alexander-alderman-webb in #5927
  • 🤖 Update test matrix with new releases (04/13) by github-actions in #5983
  • Fix license metadata in setup.py by sl0thentr0py in #5934
  • Update validate-pr workflow by stephanie-anderson in #5931

Other

  • release: 2.58.0 by ericapisani in ce445d96
  • Handle None span context in the span processor and pin tokenizers version for anthropic tests on Python 3.8 by alexander-alderman-webb in #5967

🤖 This preview updates automatically when you update the PR.

Rewrite the aiomysql integration to fix issues raised in PR getsentry#4703:

- Patch Cursor.execute and Cursor.executemany instead of Connection.query
- Make _wrap_connect async (await inside span context)
- Handle bytes/bytearray queries from executemany's internal batching
- Normalize query text using " ".join(query.split()) for performance
- Protect _sentry_skip_next_execute flag with try/finally to prevent leakage
- Remove dead _wrap_cursor and unused _record context manager

Add 17 end-to-end tests covering connect, execute, executemany, record_params,
cursor iteration, connection pools, query source, span origin, and normalization.

Update CI configuration: tox.ini envlist, GitHub Actions workflow with MySQL
service container, and test suite config.

Co-Authored-By: Qwen Code <noreply@anthropic.com>

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
tonal and others added 3 commits April 13, 2026 11:25
- Add AioMySQLIntegration to _AUTO_ENABLING_INTEGRATIONS and _MIN_VERSIONS
  (fixes sentry bot: auto-enabling and minimum version check)
- Protect _sentry_skip_next_execute flag with try/finally in _wrap_executemany
  and do NOT reset it in _wrap_execute (fixes cursor bot: flag resets prematurely
  on non-INSERT row-by-row fallback)
- Normalize query text using " ".join(query.split()) instead of re.sub
  for performance
- Fix duplicate YAML keys bug in test_group.jinja template that caused
  postgres service to be silently dropped when mysql service is added
- Add test for non-INSERT executemany (row-by-row fallback)

Co-Authored-By: Qwen Code <noreply@anthropic.com>

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
# Conflicts:
#	.github/workflows/test-integrations-dbs.yml
#	sentry_sdk/integrations/aiomysql.py
#	tests/integrations/aiomysql/test_aiomysql.py
The leftover {% if needs_mysql %} block created duplicate 'services:' and
'env:' keys, causing YAML parsers to silently overwrite earlier definitions.

Co-Authored-By: Qwen Code <noreply@anthropic.com>

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
…ction

Fixes sentry bot review comment on PR getsentry#4703.

Co-Authored-By: Qwen Code <noreply@anthropic.com>

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
@tonal
Copy link
Copy Markdown
Author

tonal commented Apr 13, 2026

@antonpirker All cursor comments are now addressed! Here is a summary of all the fixes:

  • Integration now patches Cursor.execute and Cursor.executemany instead of Connection.query (the original approach used a non-standard internal API)
  • _wrap_connect is now properly async (awaits inside the span context)
  • Query normalization handles bytes/bytearray` from executemany's internal batching
  • _sentry_skip_next_execute flag is protected with try/finally in _wrap_executemany and is no longer reset inside _wrap_execute — this prevents double-recording on non-INSERT row-by-row fallback
  • Removed the dead _wrap_cursor function
  • Integration added to _AUTO_ENABLING_INTEGRATIONS and _MIN_VERSIONS
  • Used public cursor.connection instead of private cursor._connection
  • Fixed duplicate YAML keys bug in the CI workflow template that silently dropped the postgres service when mysql was also present

@alexander-alderman-webb
18 end-to-end tests added and passing. 🙏

tonal and others added 3 commits April 13, 2026 14:14
…tional args

Fixes cursor bot comment: positional args to aiomysql.connect are now
captured correctly for span metadata.

Co-Authored-By: Qwen Code <noreply@anthropic.com>

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
- Run ruff format on aiomysql.py to satisfy lint checks
- Add cryptography to aiomysql tox deps (required for MySQL 8.0
  caching_sha2_password authentication in CI)

Co-Authored-By: Qwen Code <noreply@anthropic.com>

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
…d reconnects

- Patch Connection._connect instead of aiomysql.connect so that
  pool.py (which imports connect directly from .connection) and
  reconnects are all instrumented.
- Connection._connect has no arguments beyond self; read host/port/db/user
  directly from connection properties.
- Add assertions to test_connection_pool verifying connect spans are
  created for each pooled connection.
- Use `is not None` checks in _set_db_data to avoid skipping falsy
  but valid values (fixes cursor bot comment).
- Suppress MySQL warnings in test fixture via warnings.catch_warnings().
- Replace deprecated enable_tracing=True with traces_sample_rate=1.0
  in tests.

Co-Authored-By: Qwen Code <noreply@anthropic.com>

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 6e05b78. Configure here.

… guards

Address cursor bot comment: CONNECT WRAPPER LACKS NULL GUARDS.
Replace direct span.set_data calls with _set_db_data(span, self)
to reuse the same getattr/is-not-None logic used for query spans.

Co-Authored-By: Qwen Code <noreply@anthropic.com>

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

New Integration Integrating with a new framework or library

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants