Skip to content

Instantly share code, notes, and snippets.

@bahoo
Created June 19, 2017 23:52
Show Gist options
  • Save bahoo/b80760c157d0e3224f7196d58b22cb31 to your computer and use it in GitHub Desktop.
Save bahoo/b80760c157d0e3224f7196d58b22cb31 to your computer and use it in GitHub Desktop.
Turn a shapefile into a Django model / schema quickly.
from django.conf import settings
from django.core.management.base import BaseCommand, CommandError
from dateutil import parser
import os, untangle
class Command(BaseCommand):
ATTRIBUTE_TYPES = {
'OID': 'IntegerField',
'Geometry': 'MultiPolygonField',
'String': 'CharField',
'Integer': 'IntegerField'
}
help = 'Get a Django schema of a specified shapefile path'
def add_arguments(self, parser):
parser.add_argument('path', nargs=1, type=str)
# parser.add_argument('name', nargs=1, type=str)
def db_colname(self, col_name):
return col_name.lower().replace(' ', '_').strip()
def get_schema(self, path, name=None):
xml_file = untangle.parse(os.path.join(settings.BASE_DIR, "%s.xml" % path))
columns = ''
for i, att in enumerate(xml_file.metadata.eainfo.detailed.attr):
atts = {'null': True, 'blank': True}
field_name = self.db_colname(att.attrlabl.cdata)
field_type = self.ATTRIBUTE_TYPES[att.attrtype.cdata]
if att.attrtype.cdata == 'String':
atts['max_length'] = int(att.attwidth.cdata)
elif att.attrtype.cdata == 'Geometry':
atts['srid'] = 4326
field_name = 'geom'
columns += '\n %(field_name)s = models.%(field_type)s(%(atts)s)' % {
'field_name': field_name,
'field_type': field_type,
'atts': ', '.join('%s=%r' % x for x in atts.iteritems())
}
template_create = """
class %(name)s(models.Model):%(columns)s
"""
create = template_create % {'name' : name, 'columns' : columns}
return create
def handle(self, *args, **options):
if not '.shp' in options['path'][0]:
# todo: handle zips maybe
raise CommandError("We need a shapefile to work with")
print self.get_schema(options['path'][0], os.path.basename(options['path'][0]).split('.', 1)[0])
# ./manage.py get_schema_from_shapefile sos-data/Statewide_Prec_2016_NoWater/Statewide_Prec_2016_NoWater.shp
# class Statewide_Prec_2016_NoWater(models.Model):
# fid = models.IntegerField(null=True, blank=True)
# geom = models.MultiPolygonField(srid=4326, null=True, blank=True)
# legdist = models.CharField(max_length=80, null=True, blank=True)
# congdist = models.CharField(max_length=80, null=True, blank=True)
# ccdist = models.CharField(max_length=80, null=True, blank=True)
# county = models.CharField(max_length=50, null=True, blank=True)
# countycode = models.CharField(max_length=2, null=True, blank=True)
# preccode = models.IntegerField(null=True, blank=True)
# precname = models.CharField(max_length=50, null=True, blank=True)
# st_code = models.CharField(max_length=10, null=True, blank=True)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment