【问题标题】:SQLAlchemy datetime operations on server side服务器端的 SQLAlchemy 日期时间操作
【发布时间】:2012-09-22 02:22:14
【问题描述】:

我有一张包含预定付款和过去付款的表格,我需要查找同一周内是否有任何两次针对同一用户/合同的费用。

select count(*) from charge as c1, charge as c2 
where c1.id_contract = c2.id_contract 
  and c1.status = 'SUCCESS' 
  and c2.status in ('SUCCESS', 'PENDING', 'WAITING') 
  and c1.id > c2.id and c2.due_time > (c1.due_time - interval 7 day);

我很难在 sqlalchemy 中重现此查询,主要是因为我找不到如何以与数据库无关的形式将 MySQL 的“间隔”转换为 SQLAlchemy。

到目前为止,我想出了这个,它可以翻译所有内容,但间隔:

db.session.query(Charge, OldCharge).filter(Charge.id_contract == OldCharge.id_contract, Charge.status=='WAITING', OldCharge.status.in_(('SUCCESS', 'PENDING')), Charge.id > OldCharge.id).count()

有什么想法吗?

【问题讨论】:

    标签: mysql sqlalchemy


    【解决方案1】:

    如果您只需要 DAYs(这是默认间隔),那么只需将您的 SQL 重述为:

    c2.due_time > ADDDATE(c1.due_time, - 7)
    

    可以用 SA 术语写成:

    filter(Charge.due_time > func.ADDDATE(OldCharge.due_time, -7))
    

    如果您需要过滤不同的时间间隔类型(周、月、年),您可能需要编写自定义 SQL 构造编译器(有关详细信息,请参阅 Custom SQL Constructs and Compilation Extension)。

    【讨论】:

      【解决方案2】:

      所以,我最终编写了一个自定义 date_diff() 表达式:

      class date_diff(expression.FunctionElement):
          type = Integer()
          name = 'age'
      
      @compiles(date_diff, 'default')
      def _default_date_diff(element, compiler, **kw):  # pragma: no cover
          return "DATEDIFF(%s, %s)" % (compiler.process(element.clauses.clauses[0]),
                                       compiler.process(element.clauses.clauses[1]),
                                       )
      @compiles(date_diff, 'mysql')
      def _my_date_diff(element, compiler, **kw):  # pragma: no cover
          return "DATEDIFF(%s, %s)" % (compiler.process(element.clauses.clauses[0]),
                                       compiler.process(element.clauses.clauses[1]),
                                       )
      
      @compiles(date_diff, 'sqlite')
      def _sl_date_diff(element, compiler, **kw):    # pragma: no cover
          return "julianday(%s) - julianday(%s)" % (compiler.process(element.clauses.clauses[0]),
                                                    compiler.process(element.clauses.clauses[1]),
                                                    )
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-04-19
        • 2011-10-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-03-24
        • 1970-01-01
        相关资源
        最近更新 更多