{"library":"opentelemetry-instrumentation-sqlalchemy","title":"OpenTelemetry SQLAlchemy Instrumentation","description":"This library provides OpenTelemetry instrumentation for the SQLAlchemy Python library, allowing automatic tracing of database queries. It captures SQL statements, execution time, and connection information, providing insights into database operations within your application's distributed traces. Part of the `opentelemetry-python-contrib` project, it is currently in beta with frequent releases, often on a monthly cadence, aligning with the broader OpenTelemetry Python project.","status":"active","version":"0.61b0","language":"en","source_language":"en","source_url":"https://github.com/open-telemetry/opentelemetry-python-contrib","tags":["opentelemetry","observability","tracing","instrumentation","sqlalchemy","database","orm","sql"],"install":[{"cmd":"pip install opentelemetry-instrumentation-sqlalchemy","lang":"bash","label":"Install core instrumentation"},{"cmd":"pip install opentelemetry-sdk opentelemetry-exporter-otlp sqlalchemy","lang":"bash","label":"Required core OTel SDK, exporter, and SQLAlchemy"}],"dependencies":[{"reason":"The library instruments SQLAlchemy operations.","package":"sqlalchemy","optional":false},{"reason":"Core OpenTelemetry API for defining telemetry.","package":"opentelemetry-api","optional":false},{"reason":"Core OpenTelemetry SDK for processing and exporting telemetry.","package":"opentelemetry-sdk","optional":false},{"reason":"Common exporter for sending traces to an OTLP-compatible collector. Other exporters can be used.","package":"opentelemetry-exporter-otlp","optional":true},{"reason":"A database driver is required for SQLAlchemy to connect to a database and for the instrumentation to capture operations.","package":"SQLAlchemy-compatible database driver (e.g., psycopg2-binary, aiosqlite)","optional":false}],"imports":[{"note":"This is the main class used to instrument SQLAlchemy engines.","symbol":"SQLAlchemyInstrumentor","correct":"from opentelemetry.instrumentation.sqlalchemy import SQLAlchemyInstrumentor"}],"quickstart":{"code":"import os\nfrom opentelemetry import trace\nfrom opentelemetry.sdk.resources import Resource\nfrom opentelemetry.sdk.trace import TracerProvider\nfrom opentelemetry.sdk.trace.export import ConsoleSpanExporter, SimpleSpanProcessor\nfrom opentelemetry.instrumentation.sqlalchemy import SQLAlchemyInstrumentor\nfrom sqlalchemy import create_engine, text\n\n# Configure OpenTelemetry Tracer Provider\nresource = Resource.create({\"service.name\": os.environ.get(\"OTEL_SERVICE_NAME\", \"sqlalchemy-app\")})\ntracer_provider = TracerProvider(resource=resource)\ntracer_provider.add_span_processor(SimpleSpanProcessor(ConsoleSpanExporter()))\ntrace.set_tracer_provider(tracer_provider)\n\n# Instrument SQLAlchemy\n# For global instrumentation of all engines, call without 'engine' argument:\n# SQLAlchemyInstrumentor().instrument()\n\n# For specific engine instrumentation:\nengine = create_engine(\"sqlite:///:memory:\")\nSQLAlchemyInstrumentor().instrument(engine=engine)\n\n# Use SQLAlchemy\nwith engine.connect() as connection:\n    connection.execute(text(\"CREATE TABLE users (id INTEGER, name TEXT)\"))\n    connection.execute(text(\"INSERT INTO users (id, name) VALUES (1, 'Alice')\"))\n    connection.execute(text(\"INSERT INTO users (id, name) VALUES (2, 'Bob')\"))\n    connection.commit()\n\n    result = connection.execute(text(\"SELECT * FROM users WHERE id = 1\"))\n    for row in result:\n        print(f\"User: {row.name}\")\n\nSQLAlchemyInstrumentor().uninstrument()\nprint(\"SQLAlchemy instrumentation demonstration complete.\")","lang":"python","description":"This example demonstrates how to set up OpenTelemetry tracing and instrument a SQLAlchemy engine. It uses an in-memory SQLite database for simplicity. The `SQLAlchemyInstrumentor().instrument(engine=engine)` call enables tracing for the specified engine. You can also call `SQLAlchemyInstrumentor().instrument()` without an `engine` argument to instrument all future SQLAlchemy engines created after that call. Traces are exported to the console."},"warnings":[{"fix":"Review changelogs carefully when upgrading. Be prepared for potential API adjustments.","message":"This library is currently in beta (indicated by `b0` in the version number). While widely used, its API is not yet guaranteed to be stable, and breaking changes may occur in minor or patch releases leading up to a stable 1.0 version.","severity":"gotcha","affected_versions":"All versions < 1.0.0"},{"fix":"To include SQL comments in `db.statement`, explicitly enable it during instrumentation: `SQLAlchemyInstrumentor().instrument(enable_commenter=True, sqlcomment_attributes=True)`. Consider the security implications of exposing full SQL statements.","message":"The inclusion of `sqlcomment` (trace context) in the `db.statement` span attribute became opt-in. By default, full SQL statements with comments may not appear in your traces unless explicitly configured. This change was likely made for security/privacy considerations.","severity":"breaking","affected_versions":"Versions after approximately 0.50b0 (around 1.29.0) and later."},{"fix":"Ensure `SQLAlchemyInstrumentor().instrument()` is called early in your application's startup phase, ideally before any SQLAlchemy engines or sessions are initialized.","message":"Instrumentation must be enabled *before* SQLAlchemy engines or sessions are created. If an engine or session already exists when `instrument()` is called, its operations might not be captured.","severity":"gotcha","affected_versions":"All versions."},{"fix":"Only install `opentelemetry-instrumentation-sqlalchemy` to instrument SQLAlchemy-based database interactions. If you need driver-level instrumentation for cases not covered by SQLAlchemy, use that specific instrumentation but be mindful of potential overlaps.","message":"When using `opentelemetry-instrumentation-sqlalchemy`, do not install separate OpenTelemetry instrumentation packages for the underlying database drivers (e.g., `opentelemetry-instrumentation-psycopg2` for PostgreSQL or `opentelemetry-instrumentation-sqlite3`). Doing so can lead to duplicate spans or unexpected behavior.","severity":"gotcha","affected_versions":"All versions."},{"fix":"For async SQLAlchemy, ensure you are using a compatible version and consider using driver-level instrumentation (e.g., `opentelemetry-instrumentation-asyncpg` or `opentelemetry-instrumentation-aiosqlite`) alongside or instead of `opentelemetry-instrumentation-sqlalchemy` for more reliable coverage of async database operations. Always verify trace output.","message":"The instrumentation was primarily designed for synchronous SQLAlchemy. When using SQLAlchemy's async engines (e.g., `create_async_engine`), spans might not be fully or correctly captured due to differences in how event hooks fire in an async context.","severity":"gotcha","affected_versions":"All versions, especially with SQLAlchemy async API."}],"env_vars":null,"last_verified":"2026-04-06T00:00:00.000Z","next_check":"2026-07-05T00:00:00.000Z"}