SQLAlchemy:日付フィールドをフィルタリングする方法?


105

ここにモデルがあります:

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

たとえば、18〜30年の間隔ですべてのユーザーを選択するために、2つの日付の間でフィルターをかけます。

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
ところで、の代わりに'1985-01-17'、あなたも使うことができますdatetime.date(1985, 1, 17)-いくつかの環境では、簡単にアクセスしたり操作したりできるかもしれません。
トスバイト

5
@rippleslash:あなたは正しい、そして理想的にはパラメータに適切なデータ型を使用するべきです。ただし、すべてのデータベースは、ISO 8601形式の日付も理解します。これは、たまたま辞書式順序です。このため、単純な例では、通常、ISO形式の日付を使用しています。
'12

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年1月17日 午前0時 - 1988年1月17日 午後11時59分


危険:これはいくつかの明白であるかもしれないが-ので、これが唯一の作品func.dateCAST列の式から時間を削除 =>これはいませ付き平均範囲の時間!これは、時間が列にない場合にのみ機能します-このように日付にキャストするか、またはDateTimeまたはタイムスタンプになったら列を日付にする必要があります-通常、00:00で終了します(MySQLとPostgreSQLの両方でこれを行います)。より一般的な解決策は、キャストするのではなく、送信する日付を.endOfDay()に設定して、実際に1988-01-17 23:59:59データベースに送信することです。比較:)
jave.web
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.