Package: google-cloud-sqlcommenter
sqlcommenterPython modules for popular projects that add meta info to your SQL queries as comments.DjangoSQLAlchemyPsycopg2Local Installpip3install--usergoogle-cloud-sqlcommenterIf you'd like to record the OpenCensus trace context as well, just install it:pip3installgoogle-cloud-sqlcommenter[opencensus]If you'd like to record the OpenTelemetry trace context as well (Python 3+ only),
just install it:pip3installgoogle-cloud-sqlcommenter[opentelemetry]UsageDjangoAdd the provided Django middleware to your Django project's settings. All queries executed within the standard request→response cycle will have the SQL comment prepended to them.MIDDLEWARE=['google.cloud.sqlcommenter.django.middleware.SqlCommenter',...]which when viewed say on Postgresql logs, produces2019-05-2811:54:50.780PDT[64128]LOG:statement:INSERTINTO"polls_question"("question_text","pub_date")VALUES('Wassup?','2019-05-28T18:54:50.767481+00:00'::timestamptz)RETURNING"polls_question"."id"/*controller='index',framework='django%3A2.2.1',route='%5Epolls/%24'*/If you want the OpenCensus attributes included, you must set theSQLCOMMENTER_WITH_OPENCENSUSsetting toTrue.If you want the OpenTelemetry attributes included, you must set theSQLCOMMENTER_WITH_OPENTELEMETRYsetting toTrue.You cannot use OpenTelemetry and OpenCensus together, as they use the same attributes.SQLAlchemyAttach the provided event listener to thebefore_cursor_executeevent of the database engine, withretval=True. All queries executed with that engine will have the SQL comment prepended to them.importsqlalchemyfromgoogle.cloud.sqlcommenter.sqlalchemy.executorimportBeforeExecuteFactoryengine=sqlalchemy.create_engine(...)listener=BeforeExecuteFactory(with_db_driver=True,with_db_framework=True,# you may use one of opencensus or opentelemetrywith_opencensus=True,with_opentelemetry=True,)sqlalchemy.event.listen(engine,'before_cursor_execute',listener,retval=True)engine.execute(...)# comment will be added before executionwhich will produce a backend log such as when viewed on Postgresql2019-05-2811:52:06.527PDT[64087]LOG:statement:SELECT*FROMpolls_question
/*db_driver='psycopg2',framework='sqlalchemy%3A1.3.4',traceparent='00-5bd66ef5095369c7b0d1f8f4bd33716a-c532cb4098ac3dd2-01',tracestate='congo%%3Dt61rcWkgMzE%%2Crojo%%3D00f067aa0ba902b7'*/Psycopg2Use the provided cursor factory to generate database cursors. All queries executed with such cursors will have the SQL comment prepended to them.importpsycopg2fromgoogle.cloud.sqlcommenter.psycopg2.extensionimportCommenterCursorFactorycursor_factory=CommenterCursorFactory(with_db_driver=True,with_dbapi_level=True,with_dbapi_threadsafety=True,with_driver_paramstyle=True,with_libpq_version=True,# you may use one of opencensus or opentelemetrywith_opencensus=True,with_opentelemetry=True,)conn=psycopg2.connect(...,cursor_factory=cursor_factory)cursor=conn.cursor()cursor.execute(...)# comment will be added before executionwhich will produce a backend log such as when viewed on Postgresql2019-05-2802:33:25.287PDT[57302]LOG:statement:SELECT*FROM
polls_question/*db_driver='psycopg2%%3A2.8.2%%20%%28dt%%20dec%%20pq3%%20ext%%20lo64%%29',dbapi_level='2.0',dbapi_threadsafety=2,driver_paramstyle='pyformat',libpq_version=100001,traceparent='00-5bd66ef5095369c7b0d1f8f4bd33716a-c532cb4098ac3dd2-01',tracestate='congo%%3Dt61rcWkgMzE%%2Crojo%%3D00f067aa0ba902b7'*/OptionsWith Django, each option translates to a Django setting by uppercasing it and prependingSQLCOMMENTER_. For example,with_frameworkis controlled by the django settingSQLCOMMENTER_WITH_FRAMEWORK.OptionsIncluded by default?DjangoSQLAlchemypsycopg2Noteswith_framework:heavy_check_mark:Django versionFlask versionFlask versionwith_controller:heavy_check_mark:Django viewFlask endpointFlask endpointwith_route:heavy_check_mark:Django routeFlask routeFlask routewith_app_nameDjango app namewith_opencensusW3C TraceContext.Traceparent,W3C TraceContext.TracestateW3C TraceContext.Traceparent,W3C TraceContext.TracestateW3C TraceContext.Traceparent,W3C TraceContext.Tracestate[1][3]with_opentelemetryW3C TraceContext.Traceparent,W3C TraceContext.TracestateW3C TraceContext.Traceparent,W3C TraceContext.TracestateW3C TraceContext.Traceparent,W3C TraceContext.Tracestate[2][3]with_db_driverDjango DB engineSQLAlchemy DB driverpsycopg2 versionwith_db_frameworkSQLAlchemy versionwith_dbapi_threadsafetypsycopg2 thread safetywith_dbapi_levelpsycopg2 api levelwith_libpq_versionpsycopg2 libpq versionwith_driver_paramstylepsycopg2 parameter style[1]opencensusForopencensusto work correctly, note thatOpenCensus for
Pythonmust be
installed in the python environment.[2]opentelemetryForopentelemetryto work correctly, note thatOpenTelemetry for
Pythonmust be
installed in the python environment.[3]traceparent/tracestateBecause the W3C TraceContext'straceparentandtracestateare quite ephemeral per request, including these attributes can have a negative impact on query caching.