SQL Alchemy和Pyramid可以处理日期有效的场景

时间:2014-04-26 18:47:37

标签: python sqlalchemy pyramid

我正在寻找一个可以处理以下场景的Web框架(希望是Python,Postgresql和ORM):

你有一张人员表(有一个人Avril Lavigne - 有两次婚姻):

PersonID Start       End         PersonName
-------- ----------- ----------- -------------
1        27-Sep-1984 14-Jul-2006 Avril Lavigne
1        15-Jul-2006 30-Jun-2013 Avril Whibley
1        01-Jul-2013 31-Dec-9999 Avril Kroeger

你有一个作业表(这是一个人持有的工作任务等,一个人可以在不同的地方持有一个以上):

AssignID Start       End         PersonID JobID LocID
-------- ----------- ----------- -------- ----- -----
1        27-Sep-1984 26-Sep-1999 1        1     1 
1        27-Sep-1999 31-Dec-2002 1        1     2
1        01-Jan-2003 31-Dec-9999 1        1     3
2        01-Jul-2013 31-Dec-9999 1        2     3

有没有一种方法可以让Pyramid让用户选择一个生效日期(比如今天),SQL Alchemy将能够使用生效日期和SQL between加入表,以及外键加入在PersonID;带回来:

Avril Kroeger有2个作业JobID 1和2以及LocID 3。

Oracle中的SQL语句应该是:

select p.PersonName, 
       a.JobID,
       a.LocID
from   Person p,
       Assignment a
where  a.PersonID = p.PersonID
and    trunc(sysdate) between a.Start and a.End
and    trunc(sysdate) between p.Start and p.End

我只是担心我要学习另一个无法处理复合主键的Web框架以及上面的SQL外键无法处理的场景。

所以ORM基本可以处理任意查询吗?如果你去上面的场景,你是否放弃了所有的ORM速记功能?有没有更好的方法来处理上述情况。我应该将生效日期存储为会话变量吗?

我不太了解该主题以提供我的解决方案。我更多的是试图避免学习另一个无法解决上述问题的框架。

1 个答案:

答案 0 :(得分:3)

首先,Pyramid可以绝对完全处理这种情况,因为Pyramid与存储无关,所以它对数据库,SQL和其他类似东西一无所知:)换句话说,这个问题与金字塔没有任何关系

其次,SQLAlchemy支持复合主键。从头到尾,声明性类看起来像这样:

class Person(sa.Base):
    person_id = sa.Column(sa.Integer, primary_key=True)
    start = sa.Column(sa.DateTime, primary_key=True)
    end = sa.Column(sa.DateTime, primary_key=True)
    name = sa.Column(sa.String)

class Assignment(sa.Base):
    person_id = sa.Column(sa.Integer, primary_key=True)
    start = sa.Column(sa.DateTime, primary_key=True)
    end = sa.Column(sa.DateTime, primary_key=True)
    ...

,您的查询将如下所示:

(session.query(Person.name, Assignment.jobId, Assignment.LocID)
    .filter(Assignment.person_id==Person.person_id)
    .filter(sa.sql.functions.now().between(Person.start, Person.end))
    .filter(sa.sql.functions.now().between(Assignment.start, Assignment.end))
)