On Jul 8, 2010, at 2:42 PM, Chris Withers wrote:

> Hi All,
> 
> Say we have the following model:
> 
> class Price(Base):
>    __tablename__ = 'price'
>    id = Column(Integer, primary_key=True)
>    value = Column(Numeric(precision=36, scale=12))
> 
> class Instrument(Base):
>    __tablename__ = 'instrument'
>    id = Column(Integer, primary_key=True)
>    ticker = Column(String(50))
> 
> class Allocation(Base):
>    __tablename__ = 'data'
>    id = Column(Integer, primary_key=True)
>    trade_id = Column(Integer, index=True)
>    instrument_id = Column(ForeignKey(Instrument.id))
>    instrument = relationship(Instrument)
>    quantity = Column(Integer)
>    price_id = Column(ForeignKey(Price.id))
>    price = relationship(Price)
> 
> I now want to map the following class to the 'data' table:
> 
> class Trade(object):
>    __slots__ = (
>        'id',           # Allocation.trade_id
>        'intrument_id', # Allocation.instrument_id
>        'quantity',     # func.sum(Allocation.quantity)
>        'average_price',# see next line...
> # (func.sum(Allocation.price)/func.sum(Allocation.quantity)
> # Trades are mapped from Allocations by group_by(Allocation.trade_id)
>        )
> 
> ...if that sort of makes sense?
> 
> I'm not quote sure how to map this, although I guess something along the 
> lines of 
> http://www.sqlalchemy.org/docs/mappers.html#mapping-a-class-against-arbitrary-selects
> would be in order?

maybe.  I'd probably use a view, actually, but mapping to a select is the same 
idea.

> 
> However, what that example doesn't show, and what I'm keen to make work, is 
> if someone changes attributes of the mapped Trade, what I'd like to have 
> happen depends on the attribute:
> 
> id,instrument_id, - all underlying rows are updated
> quantity,average_price - an error is raised
> 
> Are there any examples of this?
> Any recommendations? ;-)

right.   that pattern seems a little crazy to me though I haven't been 
presented with your problemspace to fully appreciate it.  You'd have to conjure 
up the magic from scratch on this one, intercepting set events and/or checking 
historical stuff inside of before_flush() like we've done before.   You'd 
probably be calling expire() on any Trade objects encountered in the "dirty" 
list.

this model doesn't give you the best query capability.  if you wanted all 
trades with quantity < 100, its the awkward "select * from (select .. from data 
group by trade_id) where quantity < 100", instead of being able to just put a 
"having" inside your subquery. 

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.

Reply via email to