Сравнение отметки времени с датой в Python SQLAlchemy

У меня есть 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))

Я уже пробовал cast, извините, что забыл упомянуть об этом. Это не работает. Я также попытался создать как столбец, так и объект, если я напечатаю приведенный объект, я получаю CAST(:param_1 AS DATE)

Fotis Papadamis 18.12.2018 11:06

Сообщение обновлено. Я не понимаю, почему это не работает.

Fotis Papadamis 18.12.2018 11:25

Я использую Oracle. Моей первой мыслью было увеличить на 1 день, но мой руководитель попросил меня не использовать этот обходной путь.

Fotis Papadamis 18.12.2018 11:33

Когда я использую метку времени в Oracle SQL Developer, она возвращает дату, например, «11 ноября 2018».

Fotis Papadamis 18.12.2018 11:39

Выкидывает вот это: cx_Oracle.DatabaseError: ORA-01899: bad precision specifier Но не хочу сравнивать только день. Мне нужно сравнить всю дату.

Fotis Papadamis 18.12.2018 11:50

Здесь я достиг дна. Я подумываю использовать to_date внутри to_char внутри to_number и сравнивать их как числа, но это кажется немного преувеличенным ...

Fotis Papadamis 18.12.2018 12:59
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
6
2 284
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Поскольку 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)

Меня попросили не увеличивать на один день. Мне удалось решить проблему, мне просто нужно подождать два дня, прежде чем пометить вопрос как ответ, вы можете взглянуть на него.

Fotis Papadamis 19.12.2018 08:55

Было бы интересно услышать, почему вас спросили, поскольку это правильное решение, если вы хотите использовать существующий индекс на ActionDateTime, а не создавать индекс на основе функций. Ваше собственное решение страдает от того же, т.е. столбец скрыт от возможных существующих индексов. Также вам не следует (man) обрабатывать дату / время как текст, особенно когда существуют подходящие методы, такие как TRUNC().

Ilja Everilä 19.12.2018 09:40

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

Fotis Papadamis 19.12.2018 12:26

Другие вопросы по теме