Tag Archives: MySQL

Fix the dreaded “Not an image file” MySQL Django error: use VirtualEnv

If you develop Django using MySQL on a Mac, you’ve undoubtedly run into the “Not an image file” error for models with image fields. The problem has to do with JPEG support for Mac OS and how it interacts with Python Imaging Library. Diabolically, once you’ve installed PIL with bad JPEG support it seems impossible to fix.

My solution is to use a virtualenv. virtualenv is a python tool to create an isolated Python interpreter on your system, which allows you to control the installed packages without mussing up your main Python installation. It’s good practice to use a separate virtualenv for each project, and if you use Eclipse you usually want one for each workspace

There are, of course, other solutions to this problem (using PostgreSQL is probably one of them). The instructions here are based on this post on DjangoDays.com.

Prereqs

You’ll need to have xCode installed. Also, if you want to use Eclipse, vlku.com has an excellent screencast that covers everything.

Create a “workspace”

The best place to keep the virtualenv for your Django project is right next to your Django code. Create a directory to hold both. This can be just a plain directory, but if you’re using Eclipse make a new workspace first and complete the following steps in that workspace. If you have existing code, drop it in the root of this folder. For this tutorial let’s call the folder “myworkspace” and your project “myproject”.

Set up a Virtual Environment with –no-site-packages

Use easy_install to get virtualenv.

easy_install virtualenv

Change into the ‘myworkspace’ directory and create a new virtualenv. The key here is to use the –no-site-packages argument, which creates a Python that ignores the system packages already installed. We don’t want anything to come over from the system Python in case you’ve already installed a useless PIL.

python virtualenv.py python --no-site-packages

You now have a fresh, Django- and PIL-less Python interpreter at myworkspace/python/bin/python. The directory structure should now be as follows:

- myworkspace
+ - myproject
+ - python

Install libjpeg (JPEG Support) system wide

Here’s the key to fixing the problem, and where the DjangoDays.com post really saved my butt. Forget the virtualenv for a second, we’re installing JPEG support system wide.

  1. Download JPEG support. This little sucker keeps moving around the internet. I used version 6, which is still available here. The project is maintained my the Independent JPEG Group, who are showing version 8 as of this posting.
  2. Extract the tarball, cd into the resulting folder (in my case, it was called jpeg-6b, and install it with these changes.
    cd jpeg-6b
    cp /usr/share/libtool/config.sub .
    cp /usr/share/libtool/config.guess .
    ./configure –enable-shared
    make
    sudo mkdir -p /usr/local/include
    sudo mkdir -p /usr/local/bin
    sudo mkdir -p /usr/local/lib
    sudo mkdir -p /usr/local/man/man1
    sudo make install

Thanks DjangoDays.com.

Install PIL

Now we’ll install PIL and point it to the correctly installed JPEG Support. This is again lifted from the DjangoDays.com post.

  1. Download the PIL tarball here.
  2. Extract it, cd into the resulting folder, and edit setup.py to change these lines:
    JPEG_ROOT = none
    ZLIB_ROOT = none

    to this:

    JPEG_ROOT = “/usr/local/include”
    ZLIB_ROOT = “/usr/local/include”
  3. Install PIL with these commands:
    python setup.py build_ext -i
    python selftest.py
    sudo python setup.py install

I got 9 errors when I ran selftest.py, but kept going and haven’t seen any indication that the errors are giving me any trouble. Again, thanks DjangoDays.com.

Install Django, MySQL-python, etc.

Here’s a post a did a last year detailing Django installation on Mac OS X. That is, again, not the only way of doing it. The key here is to use the Python interpreter you just created to install Django and all it’s prereqs. You also have a virtualenv specific easy_install. Use it to install any other dependencies.

myworkspace/python/bin/python
myworkspace/python/bin/easy_install

Run your project

I’m skipping a lot of steps (and debugging) here, but assuming you’ve got your project set up correctly you should now be able to cd into the ‘myproject’ directory and run the server with the following command:

../python/bin/python manage.py runserver

As a shortcut, you can set an environment variable in the ‘myworkspace’ directory to map the command ‘python’ to /myworkspace/python/bin/python. Better yet, if you’re using Eclipse, use that Python as you’re interpreter, and configure the debugger to run the command for you.

Installing Django (1.1) and MySQL on Snow Leopard

A few days ago I posted my misadventures in setting up a Plone 3 buildout on Snow Leopard. That (fingers crossed) was a lot more complicated than getting Django going. However, I’ll also be installing MySQL (my database of choice) as a backend database. I’ll be foregoing Apache and mod_wsgi, as this is just a development instance.

Most of this is based on the excellent instructions available at the Django site

Working With What We’ve Got

The Macintosh Operating System, being the forward thinking platform that it is, already has Python 2.5 and 2.6 installed. Python 2.6 is the default (it’s the interpreter that starts when you type ‘python’ into the Terminal), and we’ll be sticking with that. It also includes Subversion, which we’ll use to download and update the Django trunk.

Where To Put Django

As my coding style has developed, I’ve gravitated more toward keeping Python libraries that need close management in my ‘home’ folder (/Users/kevin/ on my machine) and using symbolic links to get it on my Python path. It appears to me that everything installed under ‘/Library/’ is laid out quite nicely without any of my assistance, thank you very much.

Besides not wanting to play around with the system folders, there are a couple advantages to installing like this. First, I’ll want to update my Django installation as new code comes out, and it’s simpler to find stuff in your home folder. Second, keeping packages like Django in your home folder makes browsing the source code (a must in Open Source) much simpler.

You’ll see me use easy_install to get stuff for Pythons 2.5 and 2.6, but as a general rule if I have to manually install it it’s going in my home folder. For an alternative approach (i.e. installing Django in the local site-packages directory) see this post.

Getting MySQL

To paraphrase Billy Bob Thornton from The Bad News Bears, developing in Django without a database is kind of like kissing your sister. Let’s install MySQL.

There are lots of ways to install MySQL, including compiling and installing from source. As this is a Django development machine, I feel comfortable simply using an installer package. To my surprise, MySQL as of today doesn’t have a specific 10.6 installer package on their downloads page. No matter, we’ll just grab the 64-bit version for Mac OS X 5.

  1. Go to http://dev.mysql.com/downloads/mysql/5.5.html#downloads (for MySQL 5.5, the most current recommended version)
  2. Find the “Mac OS X 10.5 (x86_64)” under “Mac OS (package format)” and click “Pick a mirror”
  3. MySQL/Sun Microsystems will want to know everything about you. Go ahead and register.
  4. Pick a site, download the package, and double click to open the package
  5. Click “mysql-5.5.0-m2-osx10.5-x86_64.pkg” to begin the install
  6. OPTIONAL: click “mySQLStartupItem.pkg” to have MySQL start when you start your system
  7. Head’s Up!

    I don’t want MySQL running all the time, so I’m not going to install the MySQL Startup Item. That means that I’ll have to START MYSQL FROM TERMINAL EVERY TIME I WANT TO USE IT. I’ll show you how to make this simple a bit further down.

  8. OPTIONAL: click “MySQL.prefPane” to install a Preference Pane in the System Preference for MySQL (I didn’t do this either)
  9. Using your favorite text editor, create a new document called “.bash_profile” in your home directory (yes, the dot is supposed to be there). We’re going to add the MySQL directory to the PATH, allowing you to run MySQL commands by typing one string into the terminal (not the entire path). Add the following line to “.bash_profile” and save it.
  10. export PATH="$PATH:/usr/local/mysql/bin"
  11. You’ll need a root password for MySQL. Type the following command into Terminal, replacing “superduper” with a password you’ll remember
  12. mysqladmin -u root password superduper

To start MySQL, type the following into your Terminal

sudo mysqld_safe

You’ll be prompted for your system password. Enter it and MySQL will start running. You’ll need to leave a Terminal tab open to leaveit running. To stop MySQL, type Control+Z from the Terminal tab it’s running from. Now for Django itself.

Installing MySQLdb

MySQLdb is the Python library that let’s us manipulate a MySQLdb with Python code.

  1. Download the MySQLdb tarball from SourceForge.net
  2. Move the tarball to your user directory and un-tar it
    cd
    mv Downloads/MySQL-python-1.2.3c1.tar.gz MySQL-python-1.2.3c1.tar.gz
    tar xzvf MySQL-python-1.2.3c1.tar.gz
  3. Change into the directory your just created and install the library
    cd MySQL-python-1.2.3c1
    python setup.py install

Installing Django 1.1

Most of the Django sites I’ve installed at at version 1.1, but not all. I’ll also probably want to run the development version at some point as well. I’m going to set up the directories around Django with that in mind.

  1. Open Terminal, and create the following directory structure (some of which will already exist): /Users/kevin/src/django/core/. Working in our home directory…
    mkdir src
    cd src
    mkdir django
    cd django
    mkdir core
    cd core
  2. Download the latest stable version of Django 1.1 (it’s a tar.gz file, AKA a ‘tarball’)
  3. Unpack the Django tarball into the directory you created in step 1. Working in the ‘core’ directory…
    tar xzvf /Users/kevin/Downloads/Django-1.1.1.tar.gz
  4. Change into the directory you created in step 3
    cd Django-1.1.1
  5. Here is where I start deviating a little from the norm. I want to keep this code in my home directory, so I’m going to create a symbolic link to my Python SITE-PACKAGES directory that points to this version of Django. First, find your Site-Packages directory by typing this into Terminal
    python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"

    In my case, this returned:

    /Library/Python/2.6/site-packages

    So, to make the symbolic link (from within the Django-1.1.1 directory), I type:

    ln -s $PWD/django /Library/Python/2.6/site-packages/django

    (change the path to match your own SITE-PACKAGES directory)

  6. I’m going to want django-admin.py in my path (and you will too). Create a symbolic link to /usr/local/bin:
    sudo ln -s /Users/kevin/src/django/core/Django-1.1.1/django/bin/django-admin.py /usr/local/bin
  7. Check that you’ve installed Django correctly by starting the Python Interpreter (type ‘python’ into the command line) and try importing Django
    >>> import django

    No errors = awesomeness

This method installing Django 1.1.1 as my default Django (the Django I get when I type ‘django’ into a Python Interpreter). If you wanted to simultaneously run a different version of Django, repeat this process with the tarball for that version (or checkout the trunk from Subversion). When you create the symbolic link, name it something other than ‘django’ (i.e. ‘django-1.1.1’ or ‘django-trunk’).