Hi there,
I'd like to create a column composite for amounts of money and their
currency. However, the difficulty comes in keeping the currencies in a
separate table and enabling my composite to find this relationship.
Is there some way to set the Currency on my Money type implementation
automatically?
Apologies for the amount of code here:
from sqlalchemy import create_engine, Column, ForeignKey
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import scoped_session, sessionmaker, composite,
relationship, joinedload
from sqlalchemy.types import Integer, String, Numeric, TypeDecorator
from decimal import Decimal
import warnings
warnings.simplefilter('ignore')
class MoneyComposite(object):
def __init__(self, amount, currency):
self.amount = amount
self.currency = currency
# Set the currency on the Money type here
def __composite_values__(self):
return (self.amount, self.currency)
class MoneyType(TypeDecorator):
impl = Numeric
def __init__(self, *args, **kwargs):
super(MoneyType, self).__init__(*args, precision=11, scale=2,
**kwargs)
def process_bind_param(self, value, dialect):
if isinstance(value, Money):
value = value.value
return value
def process_result_value(self, value, dialect):
return Money(value)
class Money(object):
def __init__(self, value):
self.value = value
self.currency = Currency(symbol='USD', rate=Decimal('1.5'))
def __str__(self):
return '%s %s' % (self.currency.symbol, self.value *
self.currency.rate)
engine = create_engine('sqlite:///:memory:', echo=True)
Base = declarative_base(bind=engine)
Session = scoped_session(sessionmaker(bind=engine))
class Currency(Base):
__tablename__ = 'currencies'
symbol = Column(String, primary_key=True)
rate = Column(Numeric)
class Item(Base):
__tablename__ = 'items'
id = Column(Integer, primary_key=True)
name = Column(String(50))
price = composite(
MoneyComposite,
Column('amount', MoneyType),
Column('currency', String, ForeignKey(Currency.symbol))
)
currency = relationship(Currency)
Base.metadata.create_all()
c = Currency(symbol='USD', rate=Decimal('1.5'))
Session.add(c)
price = MoneyComposite(Money('5'), c.symbol)
i = Item(name='foobar', price=price)
Session.add(i)
Session.commit()
i = Session.query(Item).options(joinedload(Item.currency,
innerjoin=True)).first()
print i.price.amount
--
You received this message because you are subscribed to the Google Groups
"sqlalchemy" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/sqlalchemy?hl=en.