Python uselist=False, primaryjoin=和_( payrate_derived.c.person_id==外国(Time.person_id), 工作时间( 工资率从0.c.开始计算, 合并函数( c.c.期末工资率, datetime.date.max ) ) ) ) e=创建引擎(“postgresql://scott:tiger@本地主机/测试”,echo=False) Base.metadata.drop_all(e) Base.metadata.create_all(e) 会话=会话(e) p1=个人(姓名='p1') 会话.添加(p1) session.add_all([ 工资率(小时=10,开始=datetime.date(2013年5月17日),人员=p1), 工资率(小时=15,开始=datetime.date(2013年5月25日),人员=p1), 工资率(小时=20,开始=datetime.date(2013年6月10日),人员=p1), ]) session.add_all([ 时间(person=p1,workedon=datetime.date(2013年5月19日),hours=10), 时间(person=p1,workedon=datetime.date(2013年5月27日),hours=5), 时间(person=p1,workedon=datetime.date(2013年5月30日),hours=5), 时间(person=p1,workedon=datetime.date(2013,6,18),hours=12), ]) session.commit() 打印session.query(Person.name、Time.workedon、Time.hours、Time.cost)\ 从(时间)中选择\ 加入(Time.person)\ 加入(时间。工资率)\ 全部() 用于会话中的时间。查询(时间): 打印time.person.name、time.workedon、time.hours、time.payrate.hourly、time.cost
输出(第一行为聚合版本,其余为每个对象):Python uselist=False, primaryjoin=和_( payrate_derived.c.person_id==外国(Time.person_id), 工作时间( 工资率从0.c.开始计算, 合并函数( c.c.期末工资率, datetime.date.max ) ) ) ) e=创建引擎(“postgresql://scott:tiger@本地主机/测试”,echo=False) Base.metadata.drop_all(e) Base.metadata.create_all(e) 会话=会话(e) p1=个人(姓名='p1') 会话.添加(p1) session.add_all([ 工资率(小时=10,开始=datetime.date(2013年5月17日),人员=p1), 工资率(小时=15,开始=datetime.date(2013年5月25日),人员=p1), 工资率(小时=20,开始=datetime.date(2013年6月10日),人员=p1), ]) session.add_all([ 时间(person=p1,workedon=datetime.date(2013年5月19日),hours=10), 时间(person=p1,workedon=datetime.date(2013年5月27日),hours=5), 时间(person=p1,workedon=datetime.date(2013年5月30日),hours=5), 时间(person=p1,workedon=datetime.date(2013,6,18),hours=12), ]) session.commit() 打印session.query(Person.name、Time.workedon、Time.hours、Time.cost)\ 从(时间)中选择\ 加入(Time.person)\ 加入(时间。工资率)\ 全部() 用于会话中的时间。查询(时间): 打印time.person.name、time.workedon、time.hours、time.payrate.hourly、time.cost,python,sqlalchemy,calculated-columns,Python,Sqlalchemy,Calculated Columns,输出(第一行为聚合版本,其余为每个对象): 很多时候,我能给出的最好的建议就是做得与众不同。像这样的多表计算列是数据库的用途。基于时间表(或任何您想要的)构建一个视图,其中包含您的计算列,基于该视图构建一个模型,然后就可以进行设置了。这对数据库的压力可能也会小一些。这也是一个很好的例子,说明了为什么将设计限制在可以通过自动化实现的范围内是危险的。如果你在工资表上写上结束日期,这里一半的代码就消失了。我也在考虑使用开始,我更喜欢你的解释,因为它是关于隐藏复杂性的通用走查解决方案。做得很好。我只需要
很多时候,我能给出的最好的建议就是做得与众不同。像这样的多表计算列是数据库的用途。基于时间表(或任何您想要的)构建一个视图,其中包含您的计算列,基于该视图构建一个模型,然后就可以进行设置了。这对数据库的压力可能也会小一些。这也是一个很好的例子,说明了为什么将设计限制在可以通过自动化实现的范围内是危险的。如果你在工资表上写上结束日期,这里一半的代码就消失了。我也在考虑使用
开始,我更喜欢你的解释,因为它是关于隐藏复杂性的通用走查解决方案。做得很好。我只需要读完你提到的SQLAlchemy的不同部分。很明显,但我甚至没有想到它。
class Person(Base):
__tablename__ = 'person'
personID = Column(Integer, primary_key=True)
name = Column(String(30), unique=True)
class Payrate(Base):
__tablename__ = 'payrate'
payrateID = Column(Integer, primary_key=True)
personID = Column(Integer, ForeignKey('person.personID'))
hourly = Column(Integer)
starting = Column(Date)
__tableargs__ =(UniqueConstraint('personID', 'starting',
name='uc_peron_starting'))
class Time(Base):
__tablename__ = 'entry'
entryID = Column(Integer, primary_key=True)
personID = Column(Integer, ForeignKey('person.personID'))
workedon = Column(Date)
hours = Column(Integer)
person = relationship("Person")
def __repr__(self):
return "<{date} {hours}hrs ${0.cost:.02f}>".format(self,
date=self.workedon.isoformat(), hours=to_hours(self.hours))
@property
def cost(self):
'''Cost of entry
'''
## This is where I am stuck in propery query creation
return self.hours * query(Payrate).filter(
and_(Payrate.personID==personID,
Payrate.starting<=workedon
).order_by(
Payrate.starting.desc())
[(u'p1', datetime.date(2013, 5, 19), 10, 100), (u'p1', datetime.date(2013, 5, 27), 5, 75), (u'p1', datetime.date(2013, 5, 30), 5, 75), (u'p1', datetime.date(2013, 6, 18), 12, 240)]
p1 2013-05-19 10 10 100
p1 2013-05-27 5 15 75
p1 2013-05-30 5 15 75
p1 2013-06-18 12 20 240