I'm trying to write a django health check for a cloud app to determine if the server is still healthy.
One of the checks determines if the database is still accessible. And I want to test if this works, so I'm writing a django test script to verify this.
Except django is really good at keeping a database connection.
Things which haven't worked:
Using override settings:
#override_settings(DATABASES={})
def test_dead_database(self):
Popping the default database settings:
from django.conf import settings
old_db_eng = settings.DATABASES.pop('default')
But Django keeps the database alive!
How can I force the django database to go away within a test?
edit: this is made more difficult as the test suite checks against a number of database engines - so I'd prefer a django focused solution.
Related
GOAL: Run the DJANGO development server, using the TestCase database.
Case: DJANGO produces this database when running a TestCase. Now I'm filling the database using DJANGO-autofixture. It would be really nice to start the DJANGO testserver using this database, so I can checkout how the website presents it. Unfortunately, I can't find anywhere how to do this.
Writing the test database to sqlite would make sense, but I don't see an options for this.
Any hints are appreciated! Thanks!
The testcase database only lives within the context of a test. It is created, migrated, and loaded with fixtures before you run your tests. Default behavior is that after your test suite runs (fail or succeed), the database is dropped.
I recommend just loading your fixtures via the django-admin testserver yourfixture.json command
If you really wanted to but I think it is a not a good idea.
You have the option to provide a --keepdb argument to your test command. This will keep your test database after your test case runs. The name of that db will your actual dbs name prefixed with test_ You can then connect to that database via the database settings.
test keep alive and test database
look at database settings
As far as I know Django apps can't start if any of the databases set in the settings.py are down at the start of the application. Is there anyway to make Django "lazyload" the initial database connection?
I have two databases configured and one of them is a little unstable and sometimes it can be down for some seconds, but it's only used for some specific use cases of the application. As you can imagine I don't want that all the application can't start because of that. Is there any solution for that?
I'm using Django 1.6.11, and we also use Django South for database migrations (in case that it's related somehow).
I do not know how safe it is but you can do the following:
In your settings.py start with empty DATABASES:
DATABASES = {}
In your apps.py, utilize the ready() hook to establish your database connections:
from settings.py import DATABASES
class YourAppConfig(AppConfig):
def ready(self):
DATABASES.update({
Your database connections
})
Now I cannot place my hand over fire for that one, but Django will try to reinitialize the database connection when needed.
I did some more tests and problem only happens when you are using de development server python manage.py runserver. In that case, it forces a connection with the database.
Using an actual WSGI server it doesn't happen as #Alasdair informed.
#JohnMoutafis in the end I didn't test your solution, but that could work.
So I'm starting a new Django project that essentially requires the login & registration process be routed through an EXTERNAL & ALREADY created database.
Is it possible to have the User model use an EXTERNAL database table ONLY when Django is:
Logging in a user, to check if the login is valid
Registering a user, inserting data for that user in the external database
I would like for the rest of the Django server to use a local database.
If so, could someone either provide examples or guide me to documentation on the subject?
Easiest way to use multiple database with Django is to use a database routing. By default Django stick to single database, however, if you want to implement more interesting database routing system, you can define and install your own database routers.
Database routers are installed using the DATABASE_ROUTERS setting. You have to specify this setting in your settings.py file
What you have to do is write one AuthRouter as described Django documentation Django Multiple Database
"Yes, but"
What you are looking for in the docs is called "database router".
There is even an example for the auth app in the docs there.
But, there is s serious drawback to consider with this approach:
We cannot have cross-database relationships in the models. If auth tables are in a separate database, this means that any otehr app that needs a foreign key to User model is going to run into problems. You might be able to "fake" the relationships using a db that doesn't enforce relationship checks (SQLite or MyISAM/MySQL).
Out of the box, such apps are: session, authtoken, and admin (and probably more).
Alternatively, a single-sign-on solution might do a better job: django-sso, or django-mama-cas + django-cas-ng, or the commercial Stormpath.
I have a Django app that has several database backends - all connected to different instances of Postgresql database. One of them is not guaranteed to be always online. It even can be offline when application starts up.
Can I somehow configure Django to use lazy connections? I would like to:
Try querying
return "sorry, try again later" if database is offline
or return the results if database is online
Is this possible?
The original confusion is that Django tries to connect to its databases on startup. This is actually not true. Django does not connect to database, until some app tries to access the database.
Since my web application uses auth and site apps, it looks like it tries to connect on startup. But its not tied to startup, its tied to the fact that those app access the database "early".
If one defines second database backend (non-default), then Django will not try connecting to it unless application tries to query it.
So the solution was very trivial - originally I had one database that hosted both auth/site data and also "real" data that I've exposed to users. I wanted to make "real" database connection to be volatile. So I've defined separate psql backend for it and switched default backend to sqlite.
Now when trying to access "real" database through Query, I can easily wrap it with try/except and handle "Sorry, try again later" over to the user.
Update: I've noticed that entities are saved (and available at the Datastore Viewer) when I save them using views (and the create_object function). But when I use shell (manage.py shell) to create and save new entity it isn't commited to the storage (but still can be seen in Tes.objects.all()).
I started playing with the django-nonrel with google appengine and I am getting frustrated by thing as simple as saving Entities.
I've set up my environment as described in instruction. I managed to run sample application and it runs ok. I'd like to extend it so it saves my entity to the storage. To do so:
I added new django module with models.py:
from django.db import models
class Tes(models.Model):
name = models.CharField(max_length=150)
I created a script to save some data:
import os
import sys
sys.path.append("d:\\workspace\\project\\")
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
from testmodule.models import Tes
t = Tes(name="test")
t.save()
tes = Tes.objects.all()
for t in tes:
print t.name
The script runs without errrors. When I run it few times one after another, it prints more and more "test" strings. But when I try running it after a minute break the Tes.objects.all() returns nothing. During that time the datastore file changes it size (but maybe that's just some kind of logs). When I look at the http://localhost:8000/_ah/admin/datastore I can select only AhAdminXrsfToken from select field.
Anyway, what am I missing? Where I can find some kind of logs which would tell me what's wrong?
This is a gotcha that causes a lot of confusion. From the djangoappengine docs:
Also, never run manage.py runserver together with other management
commands at the same time. The changes won't take effect. That's an
App Engine SDK limitation which might get fixed in a later release.
So you can't do manage.py runserver and manage.py shell at the same time. If you do, changes to the datastore in one will not be visible in the other. There's a lock on the local datastore enforced by the App Engine SDK. Make sure you have stopped the server before you start the shell.
Shoudn't it be t.put() if you are creating an entity rather than saving it? I use put() to create an entity and it works for me. And if you import django you may want to know that there are alternatives to django such as my choice GAE + Jinja2 + WTForms especially now that google.db.djangoforms is deprecated selecting a form framework for forms, a templating engine and perhaps a db framework and you do't have to import django which often results in forcing you to import much more than you need.
So my recommendation is to avoid import django... and instead use Jinja2 + WTForms. If you really want django on app engine then you might want to check in the project www.allbuttonspressed.com that enables all django for google app engine but be certain that you need this much django when I suspect all we need is a template engine and a form framework and we can do without django.