python-2.7 - 如何在 web2py DAL 中的查询上应用用户定义的函数?
问题描述
我是 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>
解决方案
db(date_diff(db.lfm_case.Assignment_date) <= 26297435).select(orderby=db.lfm_case.title)
首先,db.lfm_case.Assignement_date
是 DALField
对象,而不是所需的日期时间对象或字符串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, ...)
请注意,如果传递给的查询只是一个未通过ordb()
与任何 DALQuery
对象连接的原始 SQL 字符串,则必须指定要选择的某些特定字段或(表示所有字段),以便 DAL 知道哪个表涉及查询(它无法从原始 SQL 字符串中确定)。&
|
.select()
db.lfm_case.ALL
推荐阅读
- python - Python Kivy 如何将使用 Python 制作的小部件注入到 kv 文件中的布局中
- php - 在 Laravel 中不返回 JSON 响应
- webpack - Webpack 热模块不刷新浏览器
- kotlin - 获取 Ktor http 请求的内容
- vue.js - Vue,更改本机事件不起作用,输入本机确实
- c# - C# eBay OAuth 合规性 API 身份验证问题
- .net-core - 粒度域事件
- java - 如何在 Selenium Webdriver POM 模型中打印 WebElement 变量名?
- android - 无法在仪表板活动中的 supportActionbar 上实现后退箭头
- c# - asp.net mvc 应用程序中常量值的单独文件