Question

I have some server startup code that is lying in the "models.py" of one of my Django apps. I need to run that code on server startup time.

The problem is, that code issues a SQL query, which prevents me from running syncdb with psycopg2 (it breaks the transaction, and tables are not created.)

Putting the code in a middleware and raising django.core.exceptions.MiddlewareNotUsed is not optimal as I'd like to have the effect in the Django shell too (and putting initialization code in a middleware doesn't sound right anyway.) Also I'd need to wait for the first request to do that. I want to run code on server startup, not when the first customer comes knocking on my website.

Server startup signals are still not implemented in Django, so that's not an option.

Thus, I'd like to somehow either:

  • check if Django is running a syncdb, so I don't do the queries,
  • or, alternatively, check it the corresponding tables are there, and if they are not, then, too, just don't do any queries

Non of the above two options have I found in any of the documentation. How do I do that? Or is there a better (i.e. sane) way of doing what I want to do?

Was it helpful?

Solution

Django should also load urls.py on startup; I cannot tell you if that's a suitable place for your code, but give it a try if you want to!

OTHER TIPS

Have you considered connecting to the post_syncdb signal? Perhaps you can run the custom SQL on receiving this signal. This may solve on part of your problem; you still have to figure out how to run the SQL on server startup.

You can put a check in settings.py:

import sys
...
IN_SYNCDB = ('syncdb' in sys.argv)

Then

if not settings.IN_SYNCDB:
    # run SQL code

How about a bit of exception handling? When doing a query but the database table does not exist, a Django.db.utils.DatabaseError is raised. Try..except the query code is the way of meeting your second criteria as I think.

Problem: models.py

class Foo(Model):
    #model definition here

def fun():
    obj=Foo.objects.get(pk=1)
    #other logics here...

fun() #This causes a DatabaseError

Solution: models.py

class Foo(Model):
    #model definition here

def fun():
    obj=Foo.objects.get(pk=1)
    #other logics here...

try:
    fun() 
except DatabaseError:
    pass
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top