Skip to content

Instantly share code, notes, and snippets.

@bruth
Last active December 28, 2015 07:49
Show Gist options
  • Save bruth/7467130 to your computer and use it in GitHub Desktop.
Save bruth/7467130 to your computer and use it in GitHub Desktop.
Django adhoc database
import string
from random import SystemRandom
from django.db import connections
key_chars = string.ascii_letters
random = SystemRandom()
class adhoc_db(object):
"""Context manager that temporarily adds a database connection.
Exceptions are passed through, but ensures the connection and
settings have been cleaned up from `connections.databases`.
Usage:
with adhoc_db(settings) as conn:
# do something with...
"""
def __init__(self, settings, alias=None):
if alias is None:
key = ''.join(random.choice(key_chars) for i in xrange(10))
# TODO should this lock?
assert alias not in connections.databases or \
connections.databases[alias] == settings
self.alias = alias
connections.databases[alias] = settings
self.connection = connections[alias]
def __enter__(self):
return self.connection
def __exit__(self, *excinfo):
self.connection.close()
del connections.databases[self.alias]
def adhoc_db_decorator(settings, alias=None):
def decorator(func):
def inner(*args, **kwargs):
with adhoc_db(settings, alias):
return func(*args, **kwargs)
return inner
return decorator
@DavidMuller
Copy link

Trying this out in the context of Django 1.8, and seems like the connection may not actually be dropped at the context manager exit:

In [9]: with adhoc_db(settings=connection_dictionary, alias=alias) as conn:
             # as expected, no key error here -- we have a live connection to our 'adhoc' db
   ...:     connections[alias]
   ...:     
        # exiting the context does, in fact, remove the alias from connections.databases
        # we, expectedly, KeyError here
In [12]: connections.databases[alias]
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-12-c2fadbc9000f> in <module>()
----> 1 connections.databases[alias]

KeyError: '/srv/gears/delete_me/temp.db'

         # I would, however, expect that accessing connections[alias] would key error as well 
         # I think right now we still have a live connections to our 'adhoc' db
In [13]: connections[alias]
Out[13]: <django.db.backends.sqlite3.base.DatabaseWrapper at 0x7fda69d21410>

I'm wondering if del connections.databases[self.alias] in line 37 should instead be

del connections[alias]

Thanks for this snippet @bruth!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment