SQLAlchemy: दिनांक फ़ील्ड को कैसे फ़िल्टर करें?


105

यहाँ मॉडल है:

class User(Base):
    ...
    birthday = Column(Date, index=True)   #in database it's like '1987-01-17'
    ...

मैं दो तिथियों के बीच फ़िल्टर करना चाहता हूं, उदाहरण के लिए अंतराल 18-30 वर्ष में सभी उपयोगकर्ताओं को चुनना।

SQLAlchemy के साथ इसे कैसे लागू करें?

मैं सोचता हूं बारे में:

query = DBSession.query(User).filter(
    and_(User.birthday >= '1988-01-17', User.birthday <= '1985-01-17')
) 

# means age >= 24 and age <= 27

मुझे पता है कि यह सही नहीं है, लेकिन सही कैसे करें?

जवाबों:


181

वास्तव में, आपकी क्वेरी टाइपो को छोड़कर सही है: आपका फ़िल्टर सभी रिकॉर्डों को छोड़कर है: आपको इसके <=लिए परिवर्तन करना चाहिए >=और इसके विपरीत:

qry = DBSession.query(User).filter(
        and_(User.birthday <= '1988-01-17', User.birthday >= '1985-01-17'))
# or same:
qry = DBSession.query(User).filter(User.birthday <= '1988-01-17').\
        filter(User.birthday >= '1985-01-17')

इसके अलावा आप उपयोग कर सकते हैं between:

qry = DBSession.query(User).filter(User.birthday.between('1985-01-17', '1988-01-17'))

28
Btw, के बजाय '1985-01-17', आप भी उपयोग कर सकते हैं datetime.date(1985, 1, 17)- कुछ वातावरण में साथ काम करना या प्राप्त करना आसान हो सकता है।
टॉसबाइट

5
@rippleslash: आप सही हैं, और आदर्श रूप से किसी को पैरामीटर के लिए उचित डेटा प्रकार का उपयोग करना चाहिए। हालाँकि सभी डेटाबेस तारीखों के लिए आईएसओ 8601 प्रारूप को भी समझते हैं, जो कि लेक्सोग्राफिक ऑर्डर भी होता है। साधारण उदाहरणों के लिए इस कारण से मैं आमतौर पर आईएसओ स्वरूपित तिथियों का उपयोग करता हूं - पढ़ने में आसान।
वैन

4
from app import SQLAlchemyDB as db

Chance.query.filter(Chance.repo_id==repo_id, 
                    Chance.status=="1", 
                    db.func.date(Chance.apply_time)<=end, 
                    db.func.date(Chance.apply_time)>=start).count()

यह बराबर है:

select
   count(id)
from
   Chance
where
   repo_id=:repo_id 
   and status='1'
   and date(apple_time) <= end
   and date(apple_time) >= start

इच्छा आपकी मदद कर सकती है।


3

यदि आप पूरी अवधि प्राप्त करना चाहते हैं :

    from sqlalchemy import and_, func

    query = DBSession.query(User).filter(and_(func.date(User.birthday) >= '1985-01-17'),\
                                              func.date(User.birthday) <= '1988-01-17'))

इसका मतलब सीमा: 1985-01-17 00:00 - 1988-01-17 23:59


DANGER: हालाँकि यह कुछ के लिए स्पष्ट हो सकता है - यह केवल इसलिए काम करता है क्योंकि स्तंभ पर CASTfunc.date करता है जो समीकरण से समय निकालता है => इसका मतलब समय के साथ सीमा नहीं है ! यह केवल तब काम करता है जब समय कॉलम में नहीं होता है - आपको इसे इस तरह से दिनांकित करना होगा, या कॉलम दिनांक बनाना होगा, एक बार जब यह DateTime या टाइमस्टैम्प है - यह आमतौर पर 00:00 (MySQL और PostgreSQL दोनों के साथ समाप्त होता है)। अधिक सामान्य समाधान कास्ट करने के लिए नहीं है, लेकिन आप जो तारीख भेज रहे हैं, उसे सेट करने के लिए .endOfDay () इसलिए आप वास्तव में डेटाबेस को भेजते हैं :)1988-01-17 23:59:59
jave.web
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.