RkBlog

Hardware, programming and astronomy tutorials and reviews.

First impressions of Django 1.7 beta upgrade in a young project

New version of Django brings new changes and some backward-incompatible. Upgrading from 1.6 to 1.7 turned out to be quite easy.

Since few days we have Django 1.7 beta, which brings many changes including built in migrations system. At the company we have one quite new project that is still in development so we decided to use it as a guinea pig and use Django 1.7b1 for it. The upgrade from 1.6 wasn't that problematic, but it required some search-and-fix actions...

Migrations, tests and the database

As the docs say we removed South migrations and created fake initial ones with Django 1.7. One migration had to be rewritten - it added functions to PostgreSQL database. So I've wrote a Python function that executed some raw SQL queries. With new migrations such operations are possible thanks to operations list and migrations.RunPython command:

def do_something(*args, **kwargs):
    print('hi!')

class Migration(migrations.Migration):
    dependencies = []
    operations = [
        migrations.RunPython(do_something)
    ]

New Django and new migrations also fixed a problem with few of our tests (before we would start to look for a hack or hidden configuration bug). Tests using those PostgreSQL functions failed as the test database didn't have them (even when tests run South migrations). After switching to Django 1.7 it started to pass nicely.

Also note that BooleanField needs a default=False for most common case. In older code it's quite easy to find it without any args (which now will cause problems as by default BooleanField will use null if no other default is provided.

Deploy

This project is developed with the help of Vagrant on which we have Ubuntu server in a configuration very close to the production one (puppet provisioning). In the place of development server we have nginx, supervisor and gunicorn. For the Vagrant development configuration we also have a Python process that looks for file changes and when they occur - restart gunicorn or do collectstatic. After upgrade to new Django gunicorn died and didn't want to start, throwing exceptions.

First culprit was deprecated gunicorn configuration. Supervisor used gunicorn_django to start gunicorn. Current and compatible way is to use gunicorn MY_APP_NAME.wsgi:application. Second problem was with django-debug-toolbar which also crashed gunicor with few exceptions. Removing it allowed Gunicorn to start. It looks like both sources of problems caused gunicorn to use gunicorn/app/django_wsgi.py file which is deprecated and incompatible with Django 1.7 (starting with imports).

When the django_wsgi.py is hit you will get:
ImportError: No module named 'django.core.management.validation'
DDT also caused other exception (no urlpatterns in urls file), but that also may have had something to do with configuration when running gunicorn directly and not via supervisor.

South drops out of dependencies. Fabfile responsible for the deploy doesn't do syncdb any more. The migrate stays, but it's Django now, not South.

Conclusions

At the moment we don't have any issues with Django 1.7 beta version. There isn't much django-related code in the project, but still - it works, it deploys. Older projects with more migrations or fixtures may have more thrilling upgrade process ;)

RkBlog

Django web framework tutorials, 23 March 2014,

Comment article