У меня есть API в Python, использующий sqlalchemy.
У меня есть строка, представляющая дату в формате ISO. Я конвертировал его с помощью datetime.strptime вот так: datetime.strptime(ToActionDateTime, '%Y-%m-%dZ').
Теперь мне нужно сравнить значение столбца таблицы, который является timestamp, с этой датой.
После преобразования исходной строки ISO результат будет выглядеть следующим образом: 2018-12-06 00:00:00. Я должен сравнивать это на равенство в зависимости от даты, а не времени, но я не могу понять это правильно. Любая помощь будет оценена.
Пример кода Python:
ToActionDateTimeObj = datetime.strptime(ToActionDateTime, '%Y-%m-%dZ')
query = query.filter(db.c.Audit.ActionDateTime <= ToActionDateTimeObj)
Редактировать:
Я также пытался реализовать cast в обеих частях уравнения, но это тоже не сработало. Мне не удается получить правильный результат, когда выбранная дата совпадает с датой отметки времени.
from sqlalchemy import Date, cast
ToActionDateTimeObj = datetime.strptime(ToActionDateTime, '%Y-%m-%dZ')
query = query.filter(cast(db.c.Audit.ActionDateTime, Date) <= cast(ToActionDateTimeObj, Date))
Сообщение обновлено. Я не понимаю, почему это не работает.
Я использую Oracle. Моей первой мыслью было увеличить на 1 день, но мой руководитель попросил меня не использовать этот обходной путь.
Когда я использую метку времени в Oracle SQL Developer, она возвращает дату, например, «11 ноября 2018».
Выкидывает вот это: cx_Oracle.DatabaseError: ORA-01899: bad precision specifier Но не хочу сравнивать только день. Мне нужно сравнить всю дату.
Здесь я достиг дна. Я подумываю использовать to_date внутри to_char внутри to_number и сравнивать их как числа, но это кажется немного преувеличенным ...






Поскольку Oracle Тип данных DATE фактически хранит и дату, и время, приведение к DATE не избавит от значения его временной части, как это было бы в большинстве других СУБД. Вместо этого можно использовать функцию TRUNC(date [, fmt]), чтобы уменьшить значение только до его части даты. В форме с одним аргументом он обрезается до ближайшего дня, или, другими словами, в качестве модели по умолчанию используется 'DD':
ToActionDateObj = datetime.strptime(ToActionDateTime, '%Y-%m-%dZ').date()
...
query = query.filter(func.trunc(db.c.Audit.ActionDateTime) <= ToActionDateObj)
Если используется форма с двумя аргументами, то спецификатор точности для дневной точности будет либо 'DDD', либо 'DD', либо 'J'.
Но это решение скрывает столбец ActionDateTime от возможных индексов. Чтобы сделать индекс запроса удобным, увеличьте дату ToActionDateObj на один день и используйте сравнение меньше:
ToActionDateObj = datetime.strptime(ToActionDateTime, '%Y-%m-%dZ').date()
ToActionDateObj += timedelta(days=1)
...
query = query.filter(db.c.Audit.ActionDateTime < ToActionDateObj)
Меня попросили не увеличивать на один день. Мне удалось решить проблему, мне просто нужно подождать два дня, прежде чем пометить вопрос как ответ, вы можете взглянуть на него.
Было бы интересно услышать, почему вас спросили, поскольку это правильное решение, если вы хотите использовать существующий индекс на ActionDateTime, а не создавать индекс на основе функций. Ваше собственное решение страдает от того же, т.е. столбец скрыт от возможных существующих индексов. Также вам не следует (man) обрабатывать дату / время как текст, особенно когда существуют подходящие методы, такие как TRUNC().
Я не знаю, почему меня попросили об этом, моей первой мыслью было увеличить на один день, но, поскольку это было отклонено, мне пришлось искать другой способ. Я ценю ваш ответ, вы действительно рассказали мне о вещах, которые я не принял во внимание, я использовал ваше первое решение, так как оно лучше моего, и отсутствие индексов не влияет на функциональность, к которой я стремлюсь.
Я уже пробовал
cast, извините, что забыл упомянуть об этом. Это не работает. Я также попытался создать как столбец, так и объект, если я напечатаю приведенный объект, я получаюCAST(:param_1 AS DATE)