Форум сайта python.su
Всем здравствуйте.
Есть база данных контактов с датами рождения.
Нужно получить из БД людей у которых день рождение в ближайшие 7 дней.
Формат даты в БД - год-месяц-день.
Так я получаю дельту в 7 дней.
today = date.today() delta = today + timedelta(days=7)
Офлайн
Для каждой записи бери месяц и день, добавляй туда текущий год и потом с этой датой проделывай вычисления на попадание в срок.
Код просто выложи, где ты там не можешь добавить этот фильтр.
Офлайн
и структуру бд - тоже неплохо было бы показать
Офлайн
Модель простая
class DBContact(Base): __tablename__ = 'contacts' id = Column(Integer, primary_key=True, index=True) name = Column(String, nullable=False, index=True) surname = Column(String, nullable=False, index=True) email = Column(String, nullable=False, index=True) phone = Column(String, nullable=False, index=True) birthday = Column(String, nullable=False, index=True) text = Column(String, nullable=True, index=True)
current_date = datetime.now().date() target_date = current_date + timedelta(days=7) birthdays = session.query(DBContact).filter( (extract('month', DBContact.birthday) == current_date.month) & (extract('day', DBContact.birthday) >= current_date.day) & (extract('day', DBContact.birthday) <= target_date.day) ).all()
Офлайн
birthday = Column(String, nullable=False, index=True)
SELECT id, "name", surname, email, phone, birthday, "text" FROM contacts WHERE numrange( (SELECT EXTRACT(DOY FROM CURRENT_DATE)) , (SELECT EXTRACT(DOY FROM CURRENT_DATE))+7 ) @> EXTRACT(DOY FROM TIMESTAMP birthday)
Отредактировано Rodegast (Сен. 20, 2023 01:05:43)
Офлайн
romario82Когда выделил через extract() день и месяц, подай эти значения в новую дату, формируемую через модуль datetime, с сегодняшним годом. Когда она будет сформирована, тогда ты её сравнишь с target_date через операцию сравнения больше меньше.
Я сделал такcurrent_date = datetime.now().date() target_date = current_date + timedelta(days=7) birthdays = session.query(DBContact).filter( (extract('month', DBContact.birthday) == current_date.month) & (extract('day', DBContact.birthday) >= current_date.day) & (extract('day', DBContact.birthday) <= target_date.day) ).all()
import datetime def compare_dates(date1, date2): if date1 < date2: return -1 elif date1 == date2: return 0 else: return 1 def create_date(day, month): out = datetime.datetime(datetime.datetime.now().year, month, day) return out current_date = datetime.datetime.now().date() target_date = current_date + datetime.timedelta(days=7) birthdays = session.query(DBContact).filter( compare_dates( create_date( extract('day', DBContact.birthday), extract('month', DBContact.birthday) ), target_date ) <= 0 ).all()
>>> import this The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better than dense. Readability counts. Special cases aren't special enough to break the rules. Although practicality beats purity. Errors should never pass silently. Unless explicitly silenced. In the face of ambiguity, refuse the temptation to guess. There should be one-- and preferably only one --obvious way to do it. Although that way may not be obvious at first unless you're Dutch. Now is better than never. Although never is often better than *right* now. If the implementation is hard to explain, it's a bad idea. If the implementation is easy to explain, it may be a good idea. Namespaces are one honking great idea -- let's do more of those! >>>
Отредактировано py.user.next (Сен. 21, 2023 01:41:24)
Офлайн
> Вот тебе пример
Ой.. а не проще просто циклом данные из таблицы выбирать и их с датой сравнивать?
Офлайн
RodegastЕсли там миллион данных, надо их фильтрануть сначала средствами СУБД, потому что в СУБД это всё оптимизированно, все эти операции. Для этого мы и делаем этот фильтр. А так-то он нафиг не нужен.
Ой.. а не проще просто циклом данные из таблицы выбирать и их с датой сравнивать?
Отредактировано py.user.next (Сен. 21, 2023 01:34:15)
Офлайн
> Для этого мы и делаем этот фильтр. А так-то он нафиг не нужен.
Это всё верно, но только твой пример как раз в лучшем случаи упадёт, а в худшем будет по одной записи доставать и фильтровать через compare_dates.
Офлайн
RodegastЗато он не будет внутрь базы заносить логику, которая там быть не должно. А падает он или нет, это надо смотреть сначала. Преждевременной оптимизацией в его коде я бы не стал заниматься, судя по тому, что он делает. Сначала надо посмотреть; может, оно просто так работать будет. Если же оптимизировать, то далеко не факт, что большая часть его кода сохранится вообще. Там вообще, может, другой подход нужен изначально.
Это всё верно, но только твой пример как раз в лучшем случаи упадёт, а в худшем будет по одной записи доставать и фильтровать через compare_dates.
Отредактировано py.user.next (Сен. 21, 2023 01:38:02)
Офлайн