2017-04-01 8 views
0

ORM으로 peewee를 사용하여 sqlite 데이터베이스에서 날짜를 검색하는 데 문제가 있습니다. 사용자가 03/31/2017과 같은 형식으로 특정 날짜를 입력하면 데이터베이스에서 유효한 날짜 임에도 불구하고 아무 것도 일어나지 않습니다. 나는 이것이 포맷팅 문제 일 것이라고 확신하지만, 검색 입력과 데이터베이스 쿼리에서 같은 형식을 사용하고 있습니다. 그래서 어떤 문제가 있을지 잘 모릅니다.Python에서 문자열을 Datetime으로 변환

from collections import OrderedDict 
import datetime 
import os 

from peewee import * 

db = SqliteDatabase('wlg.db') 

fmt = '%m/%d/%Y' 


class Entry(Model): 
    notes = TextField() 
    name = TextField() 
    task = TextField() 
    minutes = IntegerField() 
    date = DateField(formats=[fmt]) 

    class Meta: 
     database = db 


def initialize(): 
    """Create database and table if they don't exist""" 
    db.connect() 
    db.create_tables([Entry], safe=True) 


def clear(): 
    os.system('cls' if os.name == 'nt' else 'clear') 

def menu_loop(): 
    """Show the menu""" 
    choice = None 

    while choice != 'q': 
     clear() 
     print("Enter 'q' to quit") 
     for key, value in menu.items(): 
      print('{}) {}'.format(key, value.__doc__)) 
     choice = input('Action: ').lower().strip() 

     if choice in menu: 
      clear() 
      menu[choice]() 


def add_entry(): 
    """Add an entry""" 
    print("Enter your name or 'm' to return to main menu.") 
    while True: 
     name = input('> ') 
     if name.lower().strip() != 'm': 
      task = input("What task did you do? ") 
      minutes = input("How many minutes did it take? ") 
      notes = input("Please enter any notes about the task: ") 
      date = datetime.date.today().strftime(fmt) 
      Entry.create(name=name, task=task, minutes=minutes, notes=notes, date=date) 
      input("Hit Enter/Return to go back and add a task or view previous entries.") 
      break 
     else: 
      menu_loop() 


def view_entries(search_employee=None, search_date=None, search_time=None, search_term=None): 
    """View previous entries""" 
    entries = Entry.select().order_by(Entry.date.desc()) 

    if search_employee: 
     entries = entries.where(Entry.name.contains(search_employee)) 

    elif search_date: 
     dt = datetime.datetime.strptime(search_date, fmt) 
     entries = entries.where(Entry.date == dt) 

    elif search_time: 
     entries = entries.where(Entry.minutes == int(search_time)) 

    elif search_term: 
     entries = entries.where((Entry.task.contains(search_term))|(Entry.notes.contains(search_term))) 

    for entry in entries: 
     date = entry.date.strftime(fmt) 
     print(date) 
     print('='*len(date)) 
     print("Name: " + entry.name) 
     print("Task: " + entry.task) 
     print("Minutes Taken: " + str(entry.minutes)) 
     print("Task Notes: " + entry.notes) 
     print("Date: " + date) 
     print('n) next entry') 
     print('q) return to main menu') 

     next_action = input('Action: [Nq] ').lower().strip() 
     if next_action == 'q': 
      break 


def search_by_employee(): 
    view_entries(search_employee=input('Search query: ')) 


def search_by_date(): 
    view_entries(search_date=input('Enter Date in Format(mm/dd/yyyy)): ')) 


def search_by_time(): 
    view_entries(search_time=input('Search query: ')) 
    # while True: 
    #  search_time = (input('Search query: ')) 
    #  try: 
    #   search_time = int(search_time) 
    #   view_entries(search_time) 
    #  except ValueError: 
    #   print("Not a valid entry. Please try again") 


def search_by_term(): 
    view_entries(search_term = input('Search query: ')) 


def search_entries(): 
    """Search previous entries""" 
    # view_entries(input('Search query: ')) 
    while True: 
     lookup = input("Lookup by Employee(E), Date(D), Time(T) or Search Term(S): ") 
     lookup.lower() 

     if lookup == 'e': 
      search_by_employee() 
      break 
     elif lookup == 'd': 
      search_by_date() 
      break 
     elif lookup == 't': 
      search_by_time() 
      break 
     elif lookup == 's': 
      search_by_term() 
      break 
     else: 
      print("Sorry invalid option. Please try again") 


def delete_entry(entry): 
    """Delete an entry""" 
    pass 

menu = OrderedDict([ 
    ('a', add_entry), 
    ('v', view_entries), 
    ('s', search_entries) 
]) 

if __name__ == '__main__': 
    initialize() 
    menu_loop() 

답변

1

03/31/2017은 (프랑스) 유효한 날짜가 아닙니다.

로캘 별 날짜 처리를 원한다면 파이썬 datetime이 지원한다고 생각합니다. 응용 프로그램이 해외 사용자가있는 경우 2017년 1월 2일은 사용자가 온 세계의 부분에 따라 2 월 1 일 또는 1 월 2 일이기 때문에

Locale date formatting in Python

그러나, 당신은 매우 신중해야 에서.

표시 할 때 텍스트 날짜가 훨씬 더 좋습니다. 예를 들어 불어로는 "1er Février"가되지만 "2 월 1 일"은 모호하지 않으며 웹 사이트가 영어로 설정된 경우에는 문제가 없습니다.

그러나 "02/01"로 표시하면 문제가 발생합니다.

// 최종 호언 장담. 문제 설명 할 수

가설 : datetime.datetime를 사용

하지만 열은 시간이없는 날짜입니다. 전환에서 뭔가 잘못 될 수 있습니다. 적절한 유형을 사용하는 것은 항상 좋은 생각입니다.

날짜를 파이썬 날짜 개체로 올바르게 변환했는지 확인하려면 print()를 추가하십시오.

당신은 선언 :

date = DateField(formats=[fmt]) 

이 나를 그 peewee SQLite는 내부 날짜 형식 사이의 내부 변환 (ISO YYYY-MM-DD)의 일종을 수행 생각하게하는 'FMT "사양이 때문에, 가능 date 객체 대신 "mm/dd/yyyy"문자열이 필요합니다. 이것을 확인해야합니다.

또한 ORM 피어가 문제가되는 SQL 쿼리를 표시 할 수있는 방법이 있는지 확인하십시오. 이것은 실수를 명백하게해야합니다.

+0

답변 해 주셔서 감사합니다. 나는 그것이 분명히 포맷 오류라고 생각합니다. 처음 선언문에서 형식 문자열을 제거한 다음 elif search_date를 다음과 같이 변경했습니다.'dt = datetime.datetime.strptime (search_date, fmt) .date()' –

+0

그래서 한 번 문제가있었습니다. - 분명히 일치하지 않을 것입니다 ...하지만 dt를 출력 할 때 다음과 같이 나타납니다 : 2017-03-31 전혀 이해가되지 않습니다 .... –

+0

잘 다른 질문에 이것을 발견했습니다. 꽤 많이 내 문제에 대한 답변 : SQLite 문자열로 날짜를 저장합니다. 문자열은 바이트 단위로 정렬됩니다. % Y- % m- % d 이외의 형식을 사용하면 날짜가 올바르게 정렬되지 않습니다. SQLite의 경우 날짜를 % Y- % m- % d (항상 피의 기본값 임)로 저장하십시오. –