beyond ORM
from django.db import models
class Fruit(models.Model):
name = models.CharField(max_length=100, primary_key=True)
>>> fruit = Fruit.objects.create(name='Apple')
>>> fruit.name = 'Pear'
>>> fruit.save()
>>> Fruit.objects.values_list('name', flat=True)
['Apple', 'Pear']
ORM == Object Relational Mapper
Broadly speaking, a tool that associates object oriented classes with database tables.
# Create a CTE to represent every time bucket in the timeseries
# with a default count of 0
day_generator = func.generate_series(func.date_trunc(agg_unit, start),
func.date_trunc(agg_unit, end),
'1 ' + agg_unit)
defaults = select([sa.literal_column("0").label('count'),
day_generator.label('time_bucket')])\
.alias('defaults')
# Create a CTE that grabs the number of records contained in each time bucket.
# Will only have rows for buckets with records.
actuals = select([func.count(t.c.point_id).label('count'), # Count unique records
func.date_trunc(agg_unit, t.c.point_date).label('time_bucket')])\
.where(sa.and_(t.c.point_date >= start, # Only include records in time window
t.c.point_date <= end))\
.group_by('time_bucket')
# Also filter by geometry if requested
if geom:
actuals = actuals.where(t.c.geom.ST_Within(func.ST_GeomFromGeoJSON(geom)))
# Need to alias to make it usable in a subexpression
actuals = actuals.alias('actuals')
# Outer join the default and observed values to create the timeseries select statement.
# If no observed value in a bucket, use the default.
ts = select([sa.literal_column("'{}'".format(self.dataset_name)).label('dataset_name'),
defaults.c.time_bucket.label('time_bucket'),
func.coalesce(actuals.c.count, defaults.c.count).label('count')]).\
select_from(defaults.outerjoin(actuals, actuals.c.time_bucket == defaults.c.time_bucket))
from blog.models import Blog
b = Blog(name="Will's Cool Blog")
b.save()
from my_models import User
# Session is a SQLAlchemy session factory
session = Session()
ed_user = User(name='ed')
session.add(ed_user)
session.commit()