2016-08-15 5 views
1

Я использую библиотеку dbf с python3.5. В таблице DBF есть столбец с датами без времени, а другой - со временем. Хотите получить записи за последние пять минут.Python фильтрует DBF по дате (между двумя датами)

Я новичок в этом модуле и в настоящее время увидеть только два подхода, чтобы получить часть данных, хранящихся в DBF:

Во-первых, с симпатической SQL как запрос:

records = table.query("SELECT * WHERE (SA03 BETWEEN " + beforedfilter + " AND " + nowdfilter + ") AND (SA04 BETWEEN " + beforetfilter + " AND " + nowtfilter + ")") 

Этот был бы знакомым подходом, но возвращенные записи являются первыми записями из файла, а не между заданным диапазоном времени. Наверное, это потому, что запрос sql не поддерживается модулем? Или просто я что-то делаю в своем запросе? И еще одна странность в том, что после того, как будет напечатано несколько записей, я получу исключение: UnicodeDecodeError: 'ascii' codec can't decode byte 0xce in position 3: ordinal not in range(128). Насколько мне известно, в таблице нет символов не-ascii.

Другой подход использует метод по умолчанию для сужения записей по умолчанию. Попал в фильтрацию, поскольку я мог бы использовать ее, если бы хотел найти одну конкретную дату и время, но для диапазона, у меня нет подсказок как действовать.

index = table.create_index(lambda rec: rec.SA03) 
records = index.search(match=(?!)) 
+0

вы можете сделать работу запроса без использования переменных? Последнее предложение никогда не будет правдой, не так ли? –

+0

@joel goldstick: Спасибо за исправление по второму условию. Мне нужны переменные, но вот пример того, как выглядит эта строка при вставке переменных: SELECT * WHERE (SA03 BETWEEN 15/08/2016 AND 18/08/2016) AND (SA04 BENWEEN 15:39:25 AND 15 : 39: 25). Даже если я избавлюсь от второго условия, у меня создалось впечатление, что он пытается сбросить всю таблицу. И требуется некоторое время для обработки sql-запроса. – hTech

ответ

0

Самый простой способ, чтобы иметь функцию фильтрации, которая только отслеживает соответствие записей:

# lightly tested 
def last_five_minutes(record, date_field, time_field): 
    now = dbf.DateTime.now() 
    record_date = record[date_field] 
    try: 
     # if time is stored as HH:MM:SS 
     record_time = dbf.DateTime.strptime(record[time_field], '%H:%M:%S').time() 
     moment = dbf.DateTime.combine(record_date, record_time) 
     lapsed = now - moment 
    except (ValueError, TypeError): 
     # should log exceptions, not just ignore them 
     return dbf.DoNotIndex 
    if lapsed <= datetime.timedelta(seconds=300): 
     # return value to sort on 
     return moment 
    else: 
     # do not include this record 
     return dbf.DoNotIndex 

, а затем использовать его:

index = table.create_index(
     lambda rec: last_five_minutes(rec, 'date_field', 'time_field')) 
+0

Если я попробую его с помощью 'index = table.create_index (last_five_minutes ('rec', 'SA03', 'SA04'))' Исключением, которое я получу, является Файл «./log_user.py», строка 176 , in last_five_minutes запись [date_field] не является None TypeError: строковые индексы должны быть целыми числами – hTech

+0

в инструкции if закрывающей скобки отсутствует, а объявление индекса с таблицей.create_index (last_five_minutes) не работает, поскольку last_five_minutes ожидает аргументы. – hTech

+0

@hTech: Исправлена ​​ошибка 'create_index', используя лямбда. Удостоверьтесь и используйте правильное '' date_field'' и '' time_field'' для своего dbf. –