SQLAlchemy:如何过滤日期字段?
Posted
技术标签:
【中文标题】SQLAlchemy:如何过滤日期字段?【英文标题】:SQLAlchemy: how to filter date field? 【发布时间】:2012-02-12 06:59:29 【问题描述】:这是型号:
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
我知道这是不正确的,但是如何正确呢?
【问题讨论】:
【参考方案1】:事实上,您的查询是正确的,除了错字:您的过滤器排除了所有记录:您应该将<=
更改为>=
,反之亦然:
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'))
【讨论】:
顺便说一句,您也可以使用datetime.date(1985, 1, 17)
而不是 '1985-01-17'
- 在某些环境中可能更容易使用或使用。
@rippleslash:你是对的,理想情况下应该使用正确的数据类型作为参数。然而,所有数据库也理解日期的 ISO 8601 格式,这也恰好是字典顺序。出于这个原因,对于简单的示例,我通常使用 ISO 格式的日期 - 更易于阅读。
中间示例中的@van 是否包含日期?
@rohitwtbs:sqlalchemy 将简单地转换为 BETWEEN
运算符的数据库实现,因此答案将取决于 RDBMS。但我相信它在所有现代 RDBMS 中都具有包容性【参考方案2】:
如果你想得到整个时期:
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等式中的时间 => 这确实 NOT 表示 时间的范围! 这仅在时间不在列中时有效 - 您必须将其转换为 Date像这样,或者创建列日期,一旦它是日期时间或时间戳 - 它通常以 00:00 结束(mysql 和 PostgreSQL 都这样做)。更通用的解决方案不是强制转换,而是将您发送到它的日期设置为 .endOfDay() 以便您实际上将1988-01-17 23:59:59
发送到数据库比较:)【参考方案3】:
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
希望能帮到你。
【讨论】:
【参考方案4】:这是一个与最新的Flask
版本一起使用并使用flask-marshmallow
的版本。
from datetime import date, timedelta
from flask import jsonify
from app import db, ma
from app.models import User
from . import main
class UserSchema(ma.Schema):
class Meta:
fields = ('forename', 'surname', 'birthday', ...)
@main.route('/', methods=('GET',))
def get_users():
start_range = date.today() + timedelta(years=-30)
end_range = date.today() + timedelta(years=-18)
users = db.session.query(User).filter(User.birthday.between(start_range, end_range)).all()
users_schema = UserSchema(many=True)
return jsonify(users_schema.dump(users))
【讨论】:
我觉得你打错了date.today() + timedelta(years=-18)
应该叫end_range
以上是关于SQLAlchemy:如何过滤日期字段?的主要内容,如果未能解决你的问题,请参考以下文章
在 Flask-SQLAlchemy 模型上使用函数查询会给出 BaseQuery object is not callable 错误