1 """The application's model objects"""
2 import sqlalchemy as sa
3 from sqlalchemy import orm
5 from bluechips.model import meta
6 from bluechips.model import types
8 from datetime import datetime
10 def init_model(engine):
11 """Call me before using any of the tables or classes in the model"""
13 sm = orm.sessionmaker(autoflush=True, transactional=True, bind=engine)
16 meta.Session = orm.scoped_session(sm)
18 ### Database Schemas ###
20 users = sa.Table('users', meta.metadata,
21 sa.Column('id', sa.types.Integer, primary_key=True),
22 sa.Column('username', sa.types.Unicode(32), nullable=False),
23 sa.Column('name', sa.types.Unicode(64)),
24 sa.Column('resident', sa.types.Boolean, default=True)
27 expenditures = sa.Table('expenditures', meta.metadata,
28 sa.Column('id', sa.types.Integer, primary_key=True),
29 sa.Column('spender_id', sa.types.Integer,
30 sa.ForeignKey('users.id'), nullable=False),
31 sa.Column('amount', types.Currency, nullable=False),
32 sa.Column('description', sa.types.Text),
33 sa.Column('date', sa.types.Date, default=datetime.now),
34 sa.Column('entered_time', sa.types.DateTime,
38 splits = sa.Table('splits', meta.metadata,
39 sa.Column('id', sa.types.Integer, primary_key=True),
40 sa.Column('expenditure_id', sa.types.Integer,
41 sa.ForeignKey('expenditures.id'), nullable=False),
42 sa.Column('user_id', sa.types.Integer,
43 sa.ForeignKey('users.id'), nullable=False),
44 sa.Column('share', types.Currency, nullable=False)
47 subitems = sa.Table('subitems', meta.metadata,
48 sa.Column('id', sa.types.Integer, primary_key=True),
49 sa.Column('expenditure_id', sa.types.Integer,
50 sa.ForeignKey('expenditures.id'), nullable=False),
51 sa.Column('user_id', sa.types.Integer,
52 sa.ForeignKey('users.id'), nullable=False),
53 sa.Column('amount', types.Currency, nullable=False)
56 transfers = sa.Table('transfers', meta.metadata,
57 sa.Column('id', sa.types.Integer, primary_key=True),
58 sa.Column('debtor_id', sa.types.Integer,
59 sa.ForeignKey('users.id'), nullable=False),
60 sa.Column('creditor_id', sa.types.Integer,
61 sa.ForeignKey('users.id'), nullable=False),
62 sa.Column('amount', types.Currency, nullable=False),
63 sa.Column('description', sa.Text, default=None),
64 sa.Column('date', sa.types.Date, default=datetime.now),
65 sa.Column('entered_time', sa.types.DateTime,
73 return '<User: %s>' % (self.username)
75 class Expenditure(object):
77 return '<Expenditure: spender: %s spent: %s>' % (self.spender,
82 return '<Split: expense: %s user: %s share: %s>' % (self.expenditure,
86 class Subitem(object):
88 return '<Subitem: expense: %s user: %s cost: %s>' % (self.expense,
92 class Transfer(object):
94 return '<Transfer: from %s to %s for %s>' % (self.debtor,
98 ### DB/Class Mapping ###
100 orm.mapper(User, users)
102 orm.mapper(Expenditure, expenditures, order_by=expenditures.c.date.desc(),
104 'spender': orm.relation(User,
105 backref='expenditures',
109 orm.mapper(Split, splits, properties={
110 'expenditure': orm.relation(Expenditure, backref='splits'),
111 'user': orm.relation(User)
114 orm.mapper(Subitem, subitems, properties={
115 'expenditure': orm.relation(Expenditure, backref='subitems'),
116 'user': orm.relation(User)
119 orm.mapper(Transfer, transfers, order_by=transfers.c.date.desc(),
121 'debtor': orm.relation(User,
122 primaryjoin=(transfers.c.debtor_id==\
125 'creditor': orm.relation(User,
126 primaryjoin=(transfers.c.creditor_id==\
131 __all__ = ['users', 'expenditures', 'splits', 'subitems', 'transfers',
132 'User', 'Expenditure', 'Split', 'Subitem', 'Transfer',