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

사실, 오타를 제외하고는 쿼리가 맞습니다. 필터가 모든 레코드를 제외하고 있습니다. <=for를 변경해야 >=하며 그 반대도 마찬가지입니다.

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)수도 있습니다. 일부 환경에서 작업하거나 작업하는 것이 더 쉬울 수 있습니다.
tossbyte

5
@rippleslash : 당신 말이 맞고 이상적으로는 매개 변수에 적절한 데이터 유형을 사용해야합니다. 그러나 모든 데이터베이스는 날짜에 대한 ISO 8601 형식도 이해하며, 이는 사전 순이기도합니다. 이러한 이유로 간단한 예를 들면 일반적으로 ISO 형식의 날짜를 사용하므로 읽기가 더 쉽습니다.
van

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


위험 : 이 일부 자명 할 수도 있지만 - (가) 때문에에만 작동 func.date하지 CAST를 열에 식으로 시간을 제거 =>이 수행 되지 와 평균 범위 의 시간! 이것은 시간이 열에없는 경우에만 작동합니다. 이와 같이 Date로 CAST하거나 DateTime 또는 타임 스탬프가되면 Date 열을 만들어야합니다. 일반적으로 00:00으로 완료됩니다 (MySQL 및 PostgreSQL 모두이 작업을 수행함). 좀 더 일반적인 해결책은 캐스트하지 않고 보내는 날짜를 .endOfDay ()로 설정하는 것이므로 실제로 1988-01-17 23:59:59데이터베이스 비교로 보냅니다. :)
jave.web
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.