Registry /
observability / opentelemetry-instrumentation-sqlalchemy
Install & Compatibility
Where this runs
tested against v0.65b0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.910 runs
installs and imports cleanly · install 0.0s · import 0.000s · 22.6MB
glibcpy 3.10–3.910 runs
installs and imports cleanly · install 4.3s · import 0.000s · 23MB
59MB installed
● package 59MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
SQLAlchemyInstrumentor
✓ from opentelemetry.instrumentation.sqlalchemy import SQLAlchemyInstrumentor
✗ from opentelemetry.instrumentation.sqlalchemy import SQLAlchemyInstrumentor
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.
import os
from opentelemetry import trace
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import ConsoleSpanExporter, SimpleSpanProcessor
from opentelemetry.instrumentation.sqlalchemy import SQLAlchemyInstrumentor
from sqlalchemy import create_engine, text
# Configure OpenTelemetry Tracer Provider
resource = Resource.create({"service.name": os.environ.get("OTEL_SERVICE_NAME", "sqlalchemy-app")})
tracer_provider = TracerProvider(resource=resource)
tracer_provider.add_span_processor(SimpleSpanProcessor(ConsoleSpanExporter()))
trace.set_tracer_provider(tracer_provider)
# Instrument SQLAlchemy
# For global instrumentation of all engines, call without 'engine' argument:
# SQLAlchemyInstrumentor().instrument()
# For specific engine instrumentation:
engine = create_engine("sqlite:///:memory:")
SQLAlchemyInstrumentor().instrument(engine=engine)
# Use SQLAlchemy
with engine.connect() as connection:
connection.execute(text("CREATE TABLE users (id INTEGER, name TEXT)"))
connection.execute(text("INSERT INTO users (id, name) VALUES (1, 'Alice')"))
connection.execute(text("INSERT INTO users (id, name) VALUES (2, 'Bob')"))
connection.commit()
result = connection.execute(text("SELECT * FROM users WHERE id = 1"))
for row in result:
print(f"User: {row.name}")
SQLAlchemyInstrumentor().uninstrument()
print("SQLAlchemy instrumentation demonstration complete.")
Debug
Known issues
gotchaThis 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.fixReview changelogs carefully when upgrading. Be prepared for potential API adjustments.
affects: All versions < 1.0.0
breakingThe 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.fixTo 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.
affects: Versions after approximately 0.50b0 (around 1.29.0) and later.
gotchaInstrumentation 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.fixEnsure `SQLAlchemyInstrumentor().instrument()` is called early in your application's startup phase, ideally before any SQLAlchemy engines or sessions are initialized.
affects: All versions.
gotchaWhen 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.fixOnly 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.
affects: All versions.
gotchaThe 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.fixFor 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.
affects: All versions, especially with SQLAlchemy async API.
Upgrade
Version history
0.65b0latest on PyPI · released Jul 16, 2026
Audit
Dependencies
sqlalchemyrequiredThe library instruments SQLAlchemy operations.
opentelemetry-apirequiredCore OpenTelemetry API for defining telemetry.
opentelemetry-sdkrequiredCore OpenTelemetry SDK for processing and exporting telemetry.
opentelemetry-exporter-otlpoptionalCommon exporter for sending traces to an OTLP-compatible collector. Other exporters can be used.
SQLAlchemy-compatible database driver (e.g., psycopg2-binary, aiosqlite)requiredA database driver is required for SQLAlchemy to connect to a database and for the instrumentation to capture operations.