Commit c0656b37 authored by Nicolas Noé's avatar Nicolas Noé
Browse files

Basic import script + better data model.

parent 7972d7c5
......@@ -12,7 +12,7 @@ class MyAdminForm(forms.ModelForm):
model = Specimen
fields = "__all__"
widgets = {
'location': LatLongWidget
'coords': LatLongWidget
}
......
import csv
from django.core.management.base import BaseCommand, CommandError
from django.contrib.gis.geos import Point
from specimens.models import Person, SpecimenLocation, Specimen
# TODO: document use of this script:
# - export Google Sheet (specimens) as CSV (separator: comma)
# - Column name is important, not column order
# - Lat/lon use comma as a separator
class Command(BaseCommand):
help = 'Initial data import to populate the tables'
def add_arguments(self, parser):
parser.add_argument('csv_file')
parser.add_argument(
'--truncate',
action='store_true',
dest='truncate',
default=False,
help='Truncate specimens (and related) tables prior to import',
)
def handle(self, *args, **options):
self.stdout.write('Importing data from file...')
with open(options['csv_file']) as csv_file:
if options['truncate']:
self.stdout.write('Truncate existing data...', ending='')
Person.objects.all().delete()
SpecimenLocation.objects.all().delete()
Specimen.objects.all().delete()
self.stdout.write(self.style.SUCCESS('OK'))
for i, row in enumerate(csv.DictReader(csv_file, delimiter=',')):
self.stdout.write('Processing row #{i}...'.format(i=i), ending='')
# Identificators
id_first_name, id_last_name = row['Identified_by'].split()
identificator, _ = Person.objects.get_or_create(first_name=id_first_name, last_name=id_last_name)
# Specimen locations
specimen_location, _ = SpecimenLocation.objects.get_or_create(name=row['Specimen_location'])
specimen = Specimen()
specimen.specimen_location = specimen_location
if row['Latitude'] and row['Longitude']:
lat = float(row['Latitude'].replace(',','.'))
lon = float(row['Longitude'].replace(',','.'))
specimen.coords = Point(lon, lat)
specimen.comment = row['Comment']
if row['Depth']:
if '-' in row['Depth']: # It's a range
min, max = row['Depth'].split('-')
else: # Single value
min = max = row['Depth']
specimen.depth = (float(min.replace(',','.')), float(max.replace(',','.')))
specimen.identified_by = identificator
specimen.scientific_name = row['Scientific_name']
specimen.specimen_id = row['Specimen_id']
specimen.save()
self.stdout.write(self.style.SUCCESS('OK'))
# -*- coding: utf-8 -*-
# Generated by Django 1.11.2 on 2017-06-14 13:02
# Generated by Django 1.11.2 on 2017-06-15 10:51
from __future__ import unicode_literals
import django.contrib.gis.db.models.fields
import django.contrib.postgres.fields.ranges
from django.db import migrations, models
import django.db.models.deletion
......@@ -28,7 +30,8 @@ class Migration(migrations.Migration):
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('specimen_id', models.IntegerField(unique=True)),
('scientific_name', models.CharField(max_length=100)),
('depth', models.IntegerField(blank=True, null=True)),
('coords', django.contrib.gis.db.models.fields.PointField(blank=True, null=True, srid=4326)),
('depth', django.contrib.postgres.fields.ranges.FloatRangeField(blank=True, null=True)),
('comment', models.TextField(blank=True, null=True)),
('identified_by', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='specimens.Person')),
],
......@@ -42,7 +45,7 @@ class Migration(migrations.Migration):
),
migrations.AddField(
model_name='specimen',
name='location',
name='specimen_location',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='specimens.SpecimenLocation'),
),
migrations.AlterUniqueTogether(
......
from django.contrib.gis.db import models
from django.contrib.postgres.fields import FloatRangeField
class Person(models.Model):
first_name = models.CharField(max_length=100)
......@@ -13,10 +14,10 @@ class SpecimenLocation(models.Model):
class Specimen(models.Model):
specimen_id = models.IntegerField(unique=True) # ID from the lab, not Django's PK
scientific_name = models.CharField(max_length=100)
location = models.PointField()
depth = models.IntegerField(blank=True, null=True)
coords = models.PointField(blank=True, null=True)
depth = FloatRangeField(blank=True, null=True) # Waiting confirmation for unit and integer/float
identified_by = models.ForeignKey(Person)
location = models.ForeignKey(SpecimenLocation)
specimen_location = models.ForeignKey(SpecimenLocation)
comment = models.TextField(blank=True, null=True)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment