akindices/snapindices/models.py
2013-09-16 07:26:41 -08:00

195 lines
6.4 KiB
Python

# -*- coding: utf-8 -*-
from sqlalchemy import Column, ForeignKey, Integer, Float, String, DateTime, create_engine
from sqlalchemy.orm import relationship, backref
from sqlalchemy.schema import Index
from snapindices.database import Base
class UniqueMixin(object):
"""
Usage recipe from:
http://www.sqlalchemy.org/trac/wiki/UsageRecipes/UniqueObject
"""
@classmethod
def unique_hash(cls, *arg, **kw):
"""
Unique hash stub
"""
raise NotImplementedError()
@classmethod
def unique_filter(cls, query, *args, **kw):
"""
Unique filter stub
"""
raise NotImplementedError()
@classmethod
def as_unique(cls, session, *arg, **kw):
"""
as_unique
"""
return _unique(session, cls, cls.unique_hash, cls.unique_filter,
cls, arg, kw)
class Community(UniqueMixin, Base):
"""
Defines the data model for a Community
:returns Community data
"""
__tablename__ = 'communities'
id = Column(Integer, primary_key=True)
name = Column(String(50), nullable=False, unique=True)
northing = Column(Float, nullable=False)
easting = Column(Float, nullable=False)
latitude = Column(Float, nullable=False)
longitude = Column(Float, nullable=False)
temperatures = relationship("Temperature", backref='communities')
@classmethod
def unique_hash(cls, name, northing, easting, latitude, longitude):
return name
@classmethod
def unique_filter(cls, query, name, northing, easting, latitude, longitude):
return query.filter(Community.name == name,
Community.northing == northing,
Community.easting == easting,
Community.latitude == latitude,
Community.longitude == longitude)
def __init__(self, name, northing, easting, latitude, longitude):
self.name = name
self.northing = northing
self.easting = easting
self.latitude = latitude
self.longitude = longitude
def __repr__(self):
return "Community{data}".format(data=(self.name, self.northing,
self.easting, self.latitude,
self.longitude))
class Dataset(Base):
"""
Defines the data model for a Dataset
:returns Dataset data
"""
__tablename__ = 'datasets'
id = Column(Integer, primary_key=True)
datatype = Column(String(15), nullable=False)
model = Column(String(15), nullable=False)
modelname = Column(String(50), nullable=True)
scenario = Column(String(15), nullable=False)
resolution = Column(String(15), nullable=False)
temperatures = relationship("Temperature", backref='datasets')
def __init__(self, datatype, model, modelname, scenario, resolution):
self.datatype = datatype
self.model = model
self.modelname = modelname
self.scenario = scenario
self.resolution = resolution
def __repr__(self):
return "Dataset{data}".format(data=(self.datatype, self.model,
self.modelname, self.scenario,
self.resolution))
class Temperature(Base):
"""
Defines the data model for a Temperature
:returns Temperature data
"""
__tablename__ = 'temperatures'
id = Column(Integer, primary_key=True)
dataset_id = Column(Integer, ForeignKey('datasets.id'))
community_id = Column(Integer, ForeignKey('communities.id'))
year = Column(Integer, nullable=False)
january = Column(Float, nullable=False)
february = Column(Float, nullable=False)
march = Column(Float, nullable=False)
april = Column(Float, nullable=False)
may = Column(Float, nullable=False)
june = Column(Float, nullable=False)
july = Column(Float, nullable=False)
august = Column(Float, nullable=False)
september = Column(Float, nullable=False)
october = Column(Float, nullable=False)
november = Column(Float, nullable=False)
december = Column(Float, nullable=False)
updated = Column(DateTime, nullable=True)
dataset = relationship("Dataset", primaryjoin=dataset_id == Dataset.id)
def __init__(self, year, january, february, march, april, may, june,
july, august, september, october, november, december, updated):
self.year = year
self.january = january
self.february = february
self.march = march
self.april = april
self.may = may
self.june = june
self.july = july
self.august = august
self.september = september
self.october = october
self.november = november
self.december = december
self.updated = updated
def __repr__(self):
return "Temperature{data}".format(data=(self.year,
self.january,
self.february,
self.march,
self.april,
self.may,
self.june,
self.july,
self.august,
self.september,
self.october,
self.november,
self.december,
self.updated))
__table_args__ = (Index('idx_temps', 'dataset_id', 'community_id', 'year', unique=True),)
def _unique(session, cls, hashfunc, queryfunc, constructor, arg, kw):
"""
Function to checks for an existing instances
"""
cache = getattr(session, '_unique_cache', None)
if cache is None:
session._unique_cache = cache = {}
key = (cls, hashfunc(*arg, **kw))
if key in cache:
return cache[key]
else:
with session.no_autoflush:
q = session.query(cls)
q = queryfunc(q, *arg, **kw)
obj = q.first()
if not obj:
obj = constructor(*arg, **kw)
session.add(obj)
cache[key] = obj
return obj