django-pgconnection¶
django-pgconnection
provides primitives for overriding Postgres
connection and cursor objects, making it possible to do the following:
Hook into SQL generation. For example, it is not possible to log every time a SQL statement is executed in Django or annotate SQL with comments so that additional metadata is logged when executing queries. The
pgconnection.pre_execute_hook
context manager allows one to hook into SQL before it is executed.Route database traffic to a different database. Although Django provides the ability to construct custom database routers, routing to a different database has to be instrumented throughout code and can be tedious and error prone. The
pgconnection.route
context manager can route any database operations to a different database, even if it’s an external management command that has not been instrumented to use a different database.
We’ll go over some examples of how to use the functions in
django-pgconnection
.
Configuring a hook that will log SQL statements¶
In order to use pgconnection functions, be sure to configure
settings.DATABASES
like the following:
import pgconnection
DATABASES = pgconnection.configure({
'default': {
'HOST': '...'
}
})
This is an example of a hook function that logs every SQL statement:
def logging_hook(sql, sql_vars, cursor):
# Every hook is passed the raw SQL about to be executed,
# the variables for the SQL string, and the cursor object
# A hook can either return nothing or return a (sql, sql_vars)
# tuple to modify the SQL that will be executed
# Log the unformatted SQL
logging.INFO(sql)
with pgconnection.pre_execute_hook(logging_hook):
# Only log queries inside the context manager
User.objects.all()
# To use the hook for all queries, do
pgconnection.connect_pre_execute_hook(logging_hook)
As shown in the docs of the hook, one has the ability to also return a tuple of the SQL and the SQL variables in order to dynamically modify the SQL before execution
Routing a database connection¶
Do the following to route any Django queries, regardless of their origin, to a destination database:
import pgconnection
# Create a destination database configuration in the same format
# as databases in settings.DATABASES
destination = {
'NAME': 'database_name',
'HOST': 'database_host'
}
with pgconnection.route(destination):
# Any queries will go to the destination database
print(User.objects.all())