Skip to content

Instantly share code, notes, and snippets.

@dsmith
Created November 23, 2013 20:22
Show Gist options
  • Save dsmith/7619451 to your computer and use it in GitHub Desktop.
Save dsmith/7619451 to your computer and use it in GitHub Desktop.
from sqlalchemy.ext.associationproxy import association_proxy
from sqlalchemy.orm.collections import attribute_mapped_collection
from theleagues import db
from theleagues import mongodb
from theleagues.competitions import constants as COMPETITIONS
from theleagues.mixins import ImportableModel, UniqueModelMixin, APIModelMixin
from theleagues.sports import constants as SPORTS
from theleagues.competitors import constants as COMPETITORS
from theleagues.sports.models import Color, Group, CompetitionCompetitor
class Competitor(db.Model, APIModelMixin):
"""Base model for anything that can compete in a competition.
Including, but not limited to: Player, Team, Country, etc.
"""
__tablename__ = 'competitor'
id = db.Column(db.Integer, primary_key=True)
type = db.Column(db.String(20))
# proxies
competitions = association_proxy('competitor_competitions', 'competition',
creator=lambda competition: CompetitionCompetitor(competition=competition))
__mapper_args__ = {
'polymorphic_on': type,
'polymorphic_identity': 'competitor',
'with_polymorphic': '*'
}
@classmethod
def importable_type(cls):
return cls.__tablename__
class Player(Competitor, ImportableModel, UniqueModelMixin):
"""A competitor represented by a single person."""
__tablename__ = 'player'
id = db.Column(db.Integer, db.ForeignKey('competitor.id'), primary_key=True)
first_name = db.Column(db.String(50))
last_name = db.Column(db.String(50))
pic_url = db.Column(db.String(100))
hometown = db.Column(db.String(50))
weight = db.Column(db.Integer)
height = db.Column(db.Integer)
__mapper_args__ = {
'polymorphic_identity': 'player'
}
def __init__(self, first_name, last_name):
self.first_name = first_name
self.last_name = last_name
def __repr__(self):
return '%s %s' % (self.first_name, self.last_name, )
@classmethod
def unique_hash(cls):
pass
@classmethod
def unique_filter(cls):
pass
@classmethod
def importable_type(cls):
return cls.__tablename__
def api_property_names(self):
return ('id', 'type', 'league_id', 'first_name', 'last_name', 'pic_url')
class BaseballPlayer(Player, ImportableModel):
__tablename__ = 'baseball_player'
id = db.Column(db.Integer, db.ForeignKey('competitor.id'),
primary_key=True)
bats = db.Column(db.Integer)
throws = db.Column(db.Enum(*COMPETITORS.HAND_TYPE))
bats = db.Column(db.Enum(*COMPETITORS.HAND_TYPE))
number = db.Column(db.Integer)
experience = db.Column(db.Integer)
__mapper_args__ = {
'polymorphic_identity': 'baseball_player'
}
class Team(Competitor, ImportableModel, UniqueModelMixin):
"""A group of players that compete together."""
__tablename__ = 'team'
id = db.Column(db.Integer, db.ForeignKey('competitor.id'), primary_key=True)
location = db.Column(db.String(50))
name = db.Column(db.String(50))
abbreviation = db.Column(db.String(5))
logo_url = db.Column(db.String(100))
# proxies
players = association_proxy('team_players', 'player')
# TODO: It may make sense to move this to the Competitor class at some point
colors = association_proxy('team_colors', 'c',
creator=lambda k, v: TeamColor(color=v, priority=k))
__mapper_args__ = {
'polymorphic_identity': 'team'
}
def __init__(self, location, name):
self.location = location
self.name = name
def __repr__(self):
return '%s %s' % (self.location, self.name, )
@classmethod
def importable_type(cls):
return cls.__tablename__
@classmethod
def from_json(cls, data):
team = Team.as_unique(data['location'], data['name'])
if 'abbreviation' in data:
team.abbreviation = data['abbreviation']
team.logo_url = data['logo_url']
if 'colors' in data:
for color in data['colors']:
team.add_color(**color)
if 'groups' in data:
for g in data['groups']:
group = Group.as_unique(g['type'], g['identifier'])
group.competitors.append(team)
return team
@classmethod
def get(cls, location, name):
return Team.query.filter_by(location=location, name=name).first()
@classmethod
def unique_hash(cls, location, name):
return '%s:%s' % (location, name,)
@classmethod
def unique_filter(cls, query, location, name):
return query.filter_by(location=location, name=name)
def api_property_names(self):
return (
'id', 'type', 'league_id', 'location', 'name', 'abbreviation', 'logo_url', 'colors'
)
def api_related_resource_property_names(self):
return ('players', )
def add_color(self, name, hex_value, type='primary'):
color = Color(name=name, hex_value=hex_value)
self.colors[type] = color
return color
class TeamColor(db.Model, ImportableModel):
"""Association table representing colors for a team"""
__tablename__ = 'team_color'
team_id = db.Column(db.Integer, db.ForeignKey('team.id'), primary_key=True)
color_id = db.Column(db.Integer, db.ForeignKey('color.id'), primary_key=True)
priority = db.Column(db.SmallInteger, default=SPORTS.PRIMARY)
# relationships
team = db.relationship('Team',
backref=db.backref(
'team_colors', collection_class=attribute_mapped_collection('priority')
)
)
color = db.relationship('Color')
# proxies
c = association_proxy('color', 'hex_value')
@classmethod
def importable_type(cls):
return cls.__tablename__
class PlayerDocument(mongodb.DynamicDocument):
source = mongodb.StringField(max_length=50)
tags = mongodb.ListField()
league_id = mongodb.IntField()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment