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

How do I apply a user defined function on a query in web2py DAL?

我是 web2py 框架工作的新手,我正在构建一个应用程序,我需要根据我记录它们的日期从数据库中确定给定时间段(比如几个月)前的记录(Assignment_date),例如,列出 1 个月、2 个月或 3 个月大的案例。所以这就是我的做法,但它在我定义表的模型中不起作用,我有这两个函数,一个转换解析日期(来自数据库的日期),另一个根据当前系统时间和 returns 两个日期的纪元差。

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>
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() 的查询只是原始 SQL 字符串,未通过 &| 与任何 DAL Query 对象连接, 那么 .select() 必须指定一些特定的字段到 select 或 db.lfm_case.ALL (代表所有字段)以便 DAL 知道查询中涉及哪个 table (它无法从原始 SQL 字符串中确定)。