Как применить пользовательскую функцию к запросу в web2py DAL? - PullRequest
0 голосов
/ 29 июня 2018

Я новичок в фреймворке 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 (это месяц), вот функция </p>

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 голосов
/ 29 июня 2018
db(date_diff(db.lfm_case.Assignment_date) <= 26297435).select(orderby=db.lfm_case.title)

Во-первых, db.lfm_case.Assignement_date - это объект DAL Field, а не объект или строка datetime, как того требует 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() должен указать какие-либо конкретные поля для выбора или db.lfm_case.ALL (который представляет все поля), чтобы DAL знал, какая таблица задействована в запросе (он не может определить это по необработанной строке SQL).

...