Day: August 5, 2005

  • Migrating Your App to Django

    A few days ago I mentioned Changeset 384 which included a new command, django-admin.py inspectdb <dbname>. It has also been tweaked and improved since it was initially committed. The other day I tried it out on a simple database structure, but I decided to throw a more complex example at it.

    I decided to take the final depot application from the excellent Agile Web Development with Rails book. Beta books rule by the way. I executed the SQL in rails-code/depot_final/db/create.sql from the the code tarball to set up the database structure. I then created a new project with django-admin startproject and edited settings/main.py to tell Django how to log in to my mysql database. After exporting the correct DJANGO_SETTINGS_MODULE I ran django-admin.py inspectdb depot_rails which gave me the following model:

    # This is an auto-generated Django model module.
    # You'll have to do the following manually to clean this up:
    #     * Rearrange models' order
    #     * Add primary_key=True to one field in each model.
    # Feel free to rename the models, but don't rename 
    # db_table values or field names.
    #
    # Also note: You'll have to insert the output of 
    # 'django-admin.py sqlinitialdata [appname]'
    # into your database.
    
    from django.core import meta
    
    class LineItem(meta.Model):
        db_table = 'line_items'
        fields = (
            meta.IntegerField('id'),
            meta.IntegerField('product_id'),
            meta.IntegerField('order_id'),
            meta.IntegerField('quantity'),
            meta.FloatField('unit_price'),
        )
    
    class Order(meta.Model):
        db_table = 'orders'
        fields = (
            meta.IntegerField('id'),
            meta.CharField('name', maxlength=100),
            meta.CharField('email', maxlength=255),
            meta.TextField('address'),
            meta.CharField('pay_type', maxlength=10),
            meta.DateTimeField('shipped_at'),
        )
    
    class Product(meta.Model):
        db_table = 'products'
        fields = (
            meta.IntegerField('id'),
            meta.CharField('title', maxlength=100),
            meta.TextField('description'),
            meta.CharField('image_url', maxlength=200),
            meta.FloatField('price'),
            meta.DateTimeField('date_available'),
        )
    
    class User(meta.Model):
        db_table = 'users'
        fields = (
            meta.IntegerField('id'),
            meta.CharField('name', maxlength=100),
            meta.CharField('hashed_password', maxlength=40),
        )

    Per the comment block at the top, you’re not home free yet, but at lot of tedious work has been done for you. This should definitely jumpstart the porting of existing applications to the Django platform.

  • Swik is Slick

    Swik by SourceLabs is really awesome. It’s part wiki and part search engine. I first heard about it through the Django page, but have since poked around and there’s a lot of great information there. There’s a plethora of information on Ajax and related technologies, platforms, and projects. Swik is also folksonomy-enabled (buzzword++). For example, here’s the framework tag, python tag and java tag.

    It’s a great little service.

  • Geolocation Information Gaps

    I’ve been seeking out interesting data sources to plot in Google Earth after learning the basics of KML. I’ve been wanting to do something cool with NOAA’s XML weather feeds since I heard about them, so I thought I would download the 700kb list of stations serving up XML and spit out some KML from that data as a “neat” first step.

    I’ll probably still do that, but after parsing the data, I’m a bit dissapointed. As always there are huge gaps in geolocation information. In order to get my hands on the data I turned to xmltramp which is an awesome library for accessing simple XML documents in a pythonic way. I then whipped up a few lines of Python to walk through the data:

    import xmltramp # http://www.aaronsw.com/2002/xmltramp/
    
    f=open('stations.xml', 'r')
    doc=xmltramp.parse(f.read())
    count = 0
    total = 0
    for station in doc['station':]:
      total = total + 1
      sid = str(station['station_id'])
      lat = str(station['latitude'])
      lon = str(station['longitude'])
      if (lat != 'NA') and (lon != 'NA'):
        print "Station ID: " + sid + \
        " (" + lat + "," + lon + ")"
        count = count + 1
    print str(count) + " out of " + str(total) + \
    " stations are geolocated."

    Here’s the output of the above code:

    mcroydon@mobilematt:~/py/kmlist$ python kmlist.py
    Station ID: PAGM (63.46N,171.44W)
    [... snip ...]
    Station ID: KSHR (44.46.10N,106.58.08W)
    422 out of 1775 stations are geolocated.

    Well that’s a bummer. 422 out of 1775, or less than 25% of all stations are geolocated. While that’s still 422 more stations than I knew about previously, it’s a far cry from a majority of weather stations across the United States.

    Another thing you will notice is that some stations appear to be expressed in degrees in decimal form (63.46N) while others appear to use Degrees/Minutes/Seconds (44.46.10N).

    It’s gaps like these that can make working with “found” geolocation data frustrating.