SQLAlchemy:转换为日期类型

时间:2014-10-10 15:11:51

标签: python sql sqlalchemy

这是我的mssql代码段

Select
     Sum((Case
            When (me.status in ('CLOSED','VOID') and
            Convert(DATE,me.end_dt)=CONVERT(DATE,GETDATE()))
            Then 1 else 0
            end)) as completed,

     Sum((Case
            When datediff 
            ( hh, cast (CONVERT (DATE, GETDATE()) as varchar)+' '+ '00:00:00.000', me.due_dt)
            between 12 and 24 and me.status not in ('CLOSED','VOID')
            Then 1 else 0
            end)) as Count_12_to_24 

     from pvr_svc me with(nolock)

对于第一个查询块,这是我到目前为止所尝试的。

expr = func.sum(case([(and_(pvr_svc.status.in_(['CLOSED','VOID']), 
       (func.convert(DATE, pvr_svc.end_dt)== func.convert(DATE, func.current_date()))
       ),1)],else_=0)).label('com')

session.query(expr).scalar()

但是我说错了。

****** NotImplementedError:不知道如何引用文字引用值(类' sqlalchemy.types.DATE')***

我这里的问题很少,

Q1。如何将datetime列值(在上例中为me.end_dt)转换为DATE类型?

Q2。 sqlalchemy中GETDATE()的等价物是什么? (我尝试过func.current_date(),func.now())

Q3。实现mssql代码片段的最后一块的正确方法是什么?

我已经完成了sqlalchemy doc, 在stackoverflow上找到了一些信息,下面是链接,

convert selected datetime to date in sqlalchemy

Comparing Dates with SQLAlchemy, SQLite

2 个答案:

答案 0 :(得分:0)

expr = func.sum(
    case([(and_(
        pvr_svc.status.in_(['CLOSED', 'VOID']),
        func.strftime('%Y-%m-%d', pvr_svc.end_dt) == func.date('now'),
    ), 1)], else_=0)
).label("com")

这将仅对DATE(这是您想要的)进行字符串比较,但使用YYYY-MM-DD格式的字符串表示,因此所有比较都将按预期工作。

答案 1 :(得分:0)

这是我得到的解决方案,

from sqlalchemy import DATE, cast

expr1 = func.sum(case([(
        and_(
            (func.convert(literal_column('DATE'), pvr_svc.due_dt) == func.convert(literal_column('DATE'), func.getdate())), 
            pvr_svc.status.in_(['CLOSED','VOID'])
            ),1
        )],else_=0)).label('completed')

expr2 = func.sum(case([(
    and_(
        func.datediff(literal_column('hh'), cast(func.convert(literal_column('DATE'), func.getdate()), VARCHAR)
            +" "+"00:00:00.000",pvr_svc.due_dt)
            .between(0,12),~pvr_svc.status.in_(['CLOSED','VOID'])
        ),1)],else_=0)).label('Count_0_to_12')

session.query(expr1, expr2).all()

,或者

我们可以使用cast函数而不是convert函数。

expr1 = func.sum(
           case([(and_
             ((cast(pvr_svc.end_dt,DATE) == cast(func.getdate(),DATE)),
               pvr_svc.status.in_(['CLOSED','VOID'])
             ),1)],else_=0)
           ).label('com')

session.query(expr1).all()

强制转换和转换w.r.t与性能没有区别,因为强制转换函数在内部实现为sql中的转换函数。查找更多信息here