如何在web2py DAL中的查询上应用用户定义的函数?

时间:2018-06-29 10:27:13

标签: python-2.7 web2py

我是web2py框架工作的新手,我正在构建一个应用程序,在该应用程序中,需要根据数据库记录的日期(例如,Assignment_date)从数据库中确定给定时间段(例如几个月)的记录。 ,列出1个月,2个月或3个月大的案件。因此,这是我的操作方式,但是在模型中不起作用,我定义了表,我拥有这两个函数,一个函数转换已解析的日期(来自数据库的日期),另一个函数根据当前系统时间进行日期差并返回一个两个日期的时代差异。

stage =("Appeal","Investigation","Pre-Trial","Trial","Second Appeal")
status =("Draft","Open")
db.define_table('lfm_case',
            Field('title',requires=IS_NOT_EMPTY()),
            Field('Assignment_date','date',requires=IS_DATE(format=T('%Y-%m-%d'))),
            Field('problem','text'),
            Field('reference_number',requires=IS_NOT_EMPTY()),
            Field('institution'),
            Field('notes','text',requires=IS_NOT_EMPTY()),
            Field('stage',requires=(IS_IN_SET(stage,multiple=False),IS_NOT_EMPTY()),default='Investigation'),
            Field('status',requires=(IS_IN_SET(status,multiple=False),IS_NOT_EMPTY()),default='Open'),
            Field('case_scope','integer',default=1,readable=False,writable=False),
            auth.signature)

 import datetime
def to_epoch(a):
        date_obj = datetime.datetime.strptime(str(a), "%Y-%m-%d")
        epoch = int(date_obj.strftime('%s'))
    return epoch

def date_diff(b):
        current_date = datetime.datetime.now()
        current_epoch = int(current_date.strftime('%s'))
        diff = (current_epoch - to_epoch(b))
return diff

在控制器中,我有一个函数尝试运行查询以获取日期差为<= 26297435(即一个月)的所有日期,这里是函数

def list_by_date():
        rows = db(date_diff(db.lfm_case.Assignment_date) <= 26297435).select(orderby=db.lfm_case.title)
return locals()

下面是我的观点

{{extend 'layout.html'}}
    <table>
        <tr>
            <th>Date</th>
            <th>Title</th>
            <th>Status</th>
        </tr>
        {{for row in rows:}}
        <tr>
            <td>{{=row.Assignment_date}}</td>
            <td>{{=row.title}}</td>
            <td>{{=row.status}}</td>
        </tr>
        {{pass}}
    </table>

1 个答案:

答案 0 :(得分:0)

db(date_diff(db.lfm_case.Assignment_date) <= 26297435).select(orderby=db.lfm_case.title)

首先,db.lfm_case.Assignement_date是DAL Field对象,而不是date_diff要求的日期时间对象或字符串。其次,db()内的查询最终将转换为SQL以由数据库引擎执行,因此它不能涉及任意Python代码的执行-必须限于可通过SQL表示的内容。

相反,由于数据库存储的是日期值,因此您应该在查询中提供一个实际的日期以进行比较(即,不计算时间戳,而是计算关联的日期)。例如:

thirty_days_ago = datetime.datetime.now() - datetime.timedelta(days=30)
db(db.lfm_case.Assignment_date <= thirty_days_ago).select(...)

或者,不同的数据库提供它们自己的功能来进行带日期的计算,因此您可以将自己的自定义原始SQL作为DAL查询传递:

db(custom_sql_string).select(db.lfm_case.ALL, ...)

请注意,如果传递给db()的查询只是未通过Query&与任何DAL |对象联接的原始SQL字符串,则{{1 }}必须指定要选择的某些特定字段,或者指定.select()(代表所有字段),以便DAL知道查询中涉及哪个表(无法从原始SQL字符串确定该表)。