1

My question is very similar to this question

I'm just getting started with Django, and I find myself attempting to learn how it works any time I have a spare moment and my laptop available. I've found that Heroku is a pretty great place to test things, but I can't always reach the internet if I'm waiting to pick up kids, or something similar. In development, I would like to create a test that will check if a DB is accessible. If not, fail over to an SQLite DB.

I started with code heavily borrowed from here:

def pingable(hostname):
    try:
        return os.system("ping -c 1 " + hostname  + " > /dev/null 2>&1") == 0
    except:
        return False

if (not pingable(DATABASES['default']['HOST'])):
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.sqlite3',
            'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        }
    }

I simply plop that code immediately after the DATABASES variable is set. But this has a few weaknesses. The most glaring is that AWS (Which Heroku uses) doesn't respond to pings unless you specifically enable them . . . and honestly, why make things less secure if you don't have to?

So in the interest of not reinventing the wheel, this has led me to ask this question: has someone created a way to check if a Django DB is accessible?

I really only need to check Postgres . . . but I'd really love to find a generic solution, so half credit if you can point me to a solution that only works for Postgres.

Edit: To clarify, the internet itself may be available, but the necessary port(s) may be blocked by a firewall . . . it's hard to know what will be available

Community
  • 1
  • 1
Drigan
  • 200
  • 3
  • 14

1 Answers1

1

This isn't really the way to manage database settings between Heroku and your local dev machine.

Heroku manages all these sorts of settings via environment variables, which is one of the principles of the 12-factor app. They've also made a Django library, dj-database-url, which reads those env vars and automatically configures the settings appropriately.

You should use this for your database settings, and then you can set a local env var DATABASE_URL with the address of your local sqlite3 database. Then your app will automatically run in both dev and production and configure itself to point to the relevant database automatically.

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
  • 1
    OPs question was how to have it automatically detect which database to connect to based on availability. Is your answer that he should forget that and manually configure using env variables? – harmic Sep 26 '14 at 23:20
  • I don't believe this actually addresses my question about selecting based on availability. – Drigan Sep 28 '14 at 16:19
  • I guess Daniel's answer here is the way to go. The idea of an automatic failover is nice, but `pingable()` would only be called once when you start the thread. If you want to run this function every time you setup a connection to a database, things would get really slow. – Bjorn Sep 28 '14 at 18:54
  • @Bjorn: That really isn't an issue since this is a development only environment that we're talking about. A little slowness is a much smaller problem than spending a minute to edit the settings when you may only have a minute to spend. – Drigan Sep 29 '14 at 00:27