2013-07-14 21 views
2

我是烧瓶和ORM的新手,我正在为我的学习编写一个示例应用程序。查询在时间表中查找丢失的星期

我有这样的模式:

class Timesheet(Base): 
    __tablename__ = 'Timesheet' 

    id = Column(Integer, primary_key=True) 
    user_id = Column(Integer, ForeignKey('user.id'), nullable='False') 
    start_date = Column(Date, nullable=False) 
    end_date = Column(Date, nullable=False) 
    total_time = Column(String(), nullable=False) 

每个用户都需要提交自己的时间表进行每周,我们需要的,如果他错过任何报告时间表。

例如USER1时间表是这样的

Start_date | end_date 
--------------------- 
2013-07-01 | 2013-07-08 
2013-07-08 | 2013-07-15 
2013-07-22 | 2013-07-29 

我们需要报告错过(2013-07-15 | 2013-07-22)时间表

我怎样才能查询得到这个结果SQLAlchemy的?

回答

1

SQL查询只能查找数据库中的数据,而不查找缺少的数据,因此为了有效地查找缺失的时间段,您需要稍微重构数据库。

我的建议是,你用数据预填充你的表格。它的工作或多或少是这样的:

  • 在你开始输入你运行一个脚本,将一个空的时间表为所有的用户那一周结束一周时间表。该脚本将添加时间表条目,例如,将total_time字段设置为空。 (顺便说一句,我注意到这个字段是一个字符串,它不应该是一个整数?)。

  • 接下来输入您从用户处收到的时间表。这基本上只是用实际值更新空的total_time字段,因为所有时间表的记录都已经由脚本创建。

  • 现在,你可以找到一个简单的查询,查找空total_time场和打印这些记录的开始/结束日期,一些SQL可以做的非常有效,如果有对total_time领域的指标缺失时间表。

1

我会再创建一个表格:在过去和未来可能会有所有星期的记录。

Weeks: 
    id 
    start_time 
    end_time 

然后,我应该编写一个查询,它将正确连接Timesheet和Weeks表并按Timesheet.start_dat过滤为空。在这种情况下,您希望在开始日期和结束日期列上有索引。

顺便说一句,所有的用户都有同一个日历周的同一周的开始和结束日期? 如果是的话 - 我会正常化数据库,并只会添加Timesheet.week_id。

3

您正面临的问题在SQL世界中名为间隙和岛屿。您可以谷歌它(有关此主题的大量信息)或download免费从第3章SQL Server MVP深入潜水本书致力于解决这个问题。本章适应SQLAlachemy的第一个差距示例如下:

t1 = aliased(Timesheet) 
t2 = aliased(Timesheet) 

subq1 = session.query(
    func.min(t2.start_date) 
).filter(
    (t2.start_date > t1.end_date) & 
    (t2.user_id == t1.user_id) 
).correlate(t1).as_scalar() 

subq2 = session.query(t2).filter(
    (t2.start_date == t1.end_date) & 
    (t2.user_id == t1.user_id) 
).correlate(t1) 

subq3 = session.query(
    func.max(t2.start_date) 
).filter(
    t2.user_id == t1.user_id 
).correlate(t1) 

print session.query(
    t1.user_id, 
    t1.end_date.label('start_date'), 
    subq1.label('end_date') 
).filter(
    (~subq2.exists()) & 
    (t1.end_date < subq3) 
).all()