2017-04-01 7 views
0

私のsqliteデータベースで日付を検索する際にいくつかの問題があります(ORMとしてpeeweeを使用しています)。ユーザーが03/31/2017のような形式で特定の日付を入力した場合、それはデータベース内の有効な日付でも何も起こりません。私はこれが何らかの形式の問題であると確信していますが、検索入力とデータベースクエリで同じ形式を使用しています。Pythonで文字列を日時に変換する

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はここ(フランス)の有効な日付ではありません。

ロケール固有の日付処理が必要な場合は、python datetimeがサポートしていると思います。

Locale date formatting in Python

アプリケーションが国際のユーザーがいる場合は2017年1月2日は、ユーザーが来るの世界の一部に応じて、2月1日または1月2日であるため、しかし、あなたは、非常に、非常に慎重でなければなりませんから。

私は、テキストの日付を表示するほうがはるかに優れています。たとえば、フランス語では "1erFévrier"になりますが、2月1日はあいまいではなく、ウェブサイトが英語に設定されている場合は絶対に問題ありません。

ただし、「02/01」と表示するとトラブルが発生します。

// End rant。

あなたの問題を説明できる仮説:datetime.datetimeのを使用して

が、あなたの列には、時間のない日付です。変換で何かが間違っている可能性があります。適切なタイプを使用することは、常に良いアイデアです。

あなたの日付がpythonの日付オブジェクトに正しく変換されるようにprint()を追加してください。

あなたが宣言:

date = DateField(formats=[fmt]) 

「FMT」の仕様がありますので、これは私はおそらくピーウィーはSQLiteの内部日付フォーマット(ISOのYYYY-MM-DD)との間の内部変換のいくつかの種類を実行することを考えて、となります日付オブジェクトの代わりに "mm/dd/yyyy"文字列が必要です。これを確認してください。

また、ORMの被保険者が発行するSQLクエリを表示する方法があるかどうかを確認してください。これにより、間違いが明らかになります。

+0

お返事ありがとうございます。私はそれが間違いなく書式設定エラーであると思います。最初の宣言から書式文字列を削除し、次にelif search_dateを次のように変更しました: 'dt = datetime.datetime.strptime(search_date、fmt).date()' –

+0

これは1つの問題でした。これは明らかに一致しませんでした...しかし、私はdtを印刷すると、次のように表示されます:2017-03-31全く意味をなさない... –

+0

よく、別の質問でこれを見つけました。かなり多くの私の問題に答えます:SQLiteは日付を文字列として格納します。文字列はバイト単位でソートされます。 %Y-%m-%d以外の形式を使用すると、日付が正しくソートされません。 SQLiteの場合、日付は常に%Y-%m-%d(これはピーエーのデフォルトです)としてください。 –

関連する問題