确定在时间范围内可用的最小用户

时间:2014-02-15 03:04:11

标签: python mysql sqlalchemy

我正在编写一个出勤/ PTO跟踪应用程序,我绝对难以确定如何确定在两个给定日期时间(开始和结束)之间工作的最小代理数量。这将用于确定代理是否可以请求关闭(如果它们在任何时候都是单独的,它们将被自动拒绝)。给出以下数据库模式:

metadata = MetaData(engine) #< engine is an already established mysql conn

# Users table declaration
self.Users = Table(
    'Users', metadata,
    Column(u'ID', Integer(), primary_key=True, nullable=False,
           index=True),
    Column(u'Username', Unicode(16), nullable=False, index=True),
    Column(u'Firstname', Unicode(16), nullable=False),
    Column(u'Lastname', Unicode(50), nullable=False, index=True),
    Column(u'Nickname', Unicode(16), nullable=False),
    Column(u'Email', Unicode(16), nullable=False),
    Column(u'AvayaID', Integer(), nullable=False, index=True),
    Column(u'ManagerID', Integer(), nullable=False, index=True),
    Column(u'ShiftID', Integer(), ForeignKey('Shifts.ID'), nullable=False),
    Column(u'DaysID', Integer(), ForeignKey('Days.ID'), nullable=False),
)

# Shifts table declaration - Shift times
self.Shifts = Table(
    'Shifts', metadata,
    Column(u'ID', Integer(), primary_key=True, nullable=False, index=True),
    Column(u'Start', DateTime()),
    Column(u'End', DateTime()),
)

#   Days table declaration - Days of week worked
self.Days = Table(
    'Days', metadata,
    Column(u'ID', Integer(), primary_key=True, nullable=False),
    Column(u'Sat', Integer(1), nullable=False),
    Column(u'Sun', Integer(1), nullable=False),
    Column(u'Mon', Integer(1), nullable=False),
    Column(u'Tue', Integer(1), nullable=False),
    Column(u'Wed', Integer(1), nullable=False),
    Column(u'Thu', Integer(1), nullable=False),
    Column(u'Fri', Integer(1), nullable=False),
    )

Users表有两个外键,对应ShiftID表中的ShiftsDaysID表中的DaysShifts表只保留可能的班次开始/结束时间,Days表包含可能的工作天数组合。加入表格会产生类似于:

的结构
{ 
  'Username' : str,    #< Agent username
  'ManagerID' : int,   #< Agent manager ID
  'Shift.Start' : time,#< Agent shift start time
  'Shift.End' : time,  #< Agent shift end time
  'Days.Sat' : bool,   #< If agent works this day normally
  'Days.Sun' : bool,   #< If agent works this day normally
  'Days.Mon' : bool,   #< If agent works this day normally
  'Days.Tue' : bool,   #< If agent works this day normally
  'Days.Wed' : bool,   #< If agent works this day normally
  'Days.Thu' : bool,   #< If agent works this day normally
  'Days.Fri' : bool,   #< If agent works this day normally
}

我需要确定在所选座席轮班期间可用的最小座席数量。

我在这里遇到了一些问题,其中一个问题是我必须考虑一夜之间的轮班(start_time&gt; end_time),而另一个问题只是在思考这个问题。我认为我的数据库模式在这里是个问题,但我想不出更好的事情,谷歌也没有帮助。

1 个答案:

答案 0 :(得分:1)

如果我理解正确,您需要关联日期,用户和班次。我会保留你的User表,然后添加如下内容:

self.Schedule = Table(
    'schedule', metadata,
    Column(u'id', Integer(), primary_key=True, nullable=False, index=True),
    Column(u'User_ID', Integer(), nullable=False, ForeignKey('User.ID')),
    Column(u'Date', DateTime(), nullable=False),
    Column(u'Shift', Integer(), nullable=False)
    UniqueConstraint('User_ID', 'Date', 'Shift', name='schedule_constraint')
)

此表将存储每位员工正在工作的每个班次的记录。它有一个约束,即date,user和shift的每个组合必须是唯一的。这样可以确保同一个人每天不能超过一次同一班次,但他们仍然可以每天工作超过一班,或超过一天。然后,您可以查询计划执行此类班次的用户数量:

session.Query(Schedule).\
        filter(Schedule.Date == '2014-02-18').\
        filter(Schedule.Shift == '1').\
        count()

简而言之,我假设班次有编号(例如1,2,3)。如果它们是变量,您可以轻松地修改它以包括开始和结束时间,并在查询中使用>=<=语句。

注意:我遵循了您的约定,但请注意SQLAlchemy Ver。 0.9声明的Integer列类型没有括号,请参阅此问题:Error in SQLAlchemy with Integer: "object() takes no parameters"