Flask-SqlAlchemy 按日期时间的时间段过滤
Flask-SqlAlchemy Filtering by time section of datetime
我希望使用 Flask-SQlAlchemy 按 Flask-Admin 中日期时间列的时间部分进行过滤。
我目前的尝试是:
class BaseTimeBetweenFilter(filters.TimeBetweenFilter):
def apply(self, query, value, alias=None):
return query.filter(cast(Doctor.datetime, Time) >= value[0],
cast(Doctor.datetime, Time) <= value[1]).all()
我已经显示了时间选择器,如果显示的话
print (value[0])
或
print (value[1])
它按预期打印出输入的时间。但是查询不起作用。
admin-panel_1 | response = self.full_dispatch_request()
admin-panel_1 | File "/usr/local/lib/python3.5/dist-packages/flask/app.py", line 1641, in full_dispatch_request
admin-panel_1 | rv = self.handle_user_exception(e)
admin-panel_1 | File "/usr/local/lib/python3.5/dist-packages/flask/app.py", line 1544, in handle_user_exception
admin-panel_1 | reraise(exc_type, exc_value, tb)
admin-panel_1 | File "/usr/local/lib/python3.5/dist-packages/flask/_compat.py", line 33, in reraise
admin-panel_1 | raise value
admin-panel_1 | File "/usr/local/lib/python3.5/dist-packages/flask/app.py", line 1639, in full_dispatch_request
admin-panel_1 | rv = self.dispatch_request()
admin-panel_1 | File "/usr/local/lib/python3.5/dist-packages/flask/app.py", line 1625, in dispatch_request
admin-panel_1 | return self.view_functionsrule.endpoint
admin-panel_1 | File "/usr/local/lib/python3.5/dist-packages/flask_admin/base.py", line 69, in inner
admin-panel_1 | return self._run_view(f, *args, **kwargs)
admin-panel_1 | File "/usr/local/lib/python3.5/dist-packages/flask_admin/base.py", line 368, in _run_view
admin-panel_1 | return fn(self, *args, **kwargs)
admin-panel_1 | File "/usr/local/lib/python3.5/dist-packages/flask_admin/model/base.py", line 1818, in index_view
admin-panel_1 | view_args.search, view_args.filters)
admin-panel_1 | File "/usr/local/lib/python3.5/dist-packages/flask_admin/contrib/sqla/view.py", line 975, in get_list
admin-panel_1 | count = count_query.scalar() if count_query else None
admin-panel_1 | AttributeError: 'list' object has no attribute 'scalar'
此外,我从 sqlalchemy 导入了 Time 和 Cast,这样可以吗,还是我应该从 flask-sqlalchemy 获取它?
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import Time, cast
Flask-Admin 通过连接表、应用过滤器和排序来构建查询。在完成所有这些过程后,它会调用查询本身并获取结果。
您的 apply
方法应该 return sqlalchemy.orm.query.Query
实例作为它作为 query
参数获得的实例。当您添加 .all()
方法时,将调用此查询并获得查询结果列表。从结果值中删除 .all()
调用,您的过滤器应该可以工作:
class BaseTimeBetweenFilter(filters.TimeBetweenFilter):
def apply(self, query, value, alias=None):
return query.filter(
cast(Doctor.datetime, Time) >= value[0],
cast(Doctor.datetime, Time) <= value[1]
)
导入的来源并不重要。 flask_sqlalchemy.SQLAlchemy
实例包含与 sqlalchemy
相同的对象:
>>> from flask_sqlalchemy import SQLAlchemy
>>> db = SQLAlchemy()
>>> db.Time
<class 'sqlalchemy.sql.sqltypes.Time'>
>>> db.cast
<function cast at 0x7f60a3e89c80>
>>> from sqlalchemy import Time, cast
>>> Time
<class 'sqlalchemy.sql.sqltypes.Time'>
>>> cast
<function cast at 0x7f60a3e89c80>
>>> db.cast == cast and db.Time == Time
True
我希望使用 Flask-SQlAlchemy 按 Flask-Admin 中日期时间列的时间部分进行过滤。
我目前的尝试是:
class BaseTimeBetweenFilter(filters.TimeBetweenFilter):
def apply(self, query, value, alias=None):
return query.filter(cast(Doctor.datetime, Time) >= value[0],
cast(Doctor.datetime, Time) <= value[1]).all()
我已经显示了时间选择器,如果显示的话
print (value[0])
或
print (value[1])
它按预期打印出输入的时间。但是查询不起作用。
admin-panel_1 | response = self.full_dispatch_request()
admin-panel_1 | File "/usr/local/lib/python3.5/dist-packages/flask/app.py", line 1641, in full_dispatch_request
admin-panel_1 | rv = self.handle_user_exception(e)
admin-panel_1 | File "/usr/local/lib/python3.5/dist-packages/flask/app.py", line 1544, in handle_user_exception
admin-panel_1 | reraise(exc_type, exc_value, tb)
admin-panel_1 | File "/usr/local/lib/python3.5/dist-packages/flask/_compat.py", line 33, in reraise
admin-panel_1 | raise value
admin-panel_1 | File "/usr/local/lib/python3.5/dist-packages/flask/app.py", line 1639, in full_dispatch_request
admin-panel_1 | rv = self.dispatch_request()
admin-panel_1 | File "/usr/local/lib/python3.5/dist-packages/flask/app.py", line 1625, in dispatch_request
admin-panel_1 | return self.view_functionsrule.endpoint
admin-panel_1 | File "/usr/local/lib/python3.5/dist-packages/flask_admin/base.py", line 69, in inner
admin-panel_1 | return self._run_view(f, *args, **kwargs)
admin-panel_1 | File "/usr/local/lib/python3.5/dist-packages/flask_admin/base.py", line 368, in _run_view
admin-panel_1 | return fn(self, *args, **kwargs)
admin-panel_1 | File "/usr/local/lib/python3.5/dist-packages/flask_admin/model/base.py", line 1818, in index_view
admin-panel_1 | view_args.search, view_args.filters)
admin-panel_1 | File "/usr/local/lib/python3.5/dist-packages/flask_admin/contrib/sqla/view.py", line 975, in get_list
admin-panel_1 | count = count_query.scalar() if count_query else None
admin-panel_1 | AttributeError: 'list' object has no attribute 'scalar'
此外,我从 sqlalchemy 导入了 Time 和 Cast,这样可以吗,还是我应该从 flask-sqlalchemy 获取它?
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import Time, cast
Flask-Admin 通过连接表、应用过滤器和排序来构建查询。在完成所有这些过程后,它会调用查询本身并获取结果。
您的 apply
方法应该 return sqlalchemy.orm.query.Query
实例作为它作为 query
参数获得的实例。当您添加 .all()
方法时,将调用此查询并获得查询结果列表。从结果值中删除 .all()
调用,您的过滤器应该可以工作:
class BaseTimeBetweenFilter(filters.TimeBetweenFilter):
def apply(self, query, value, alias=None):
return query.filter(
cast(Doctor.datetime, Time) >= value[0],
cast(Doctor.datetime, Time) <= value[1]
)
导入的来源并不重要。 flask_sqlalchemy.SQLAlchemy
实例包含与 sqlalchemy
相同的对象:
>>> from flask_sqlalchemy import SQLAlchemy
>>> db = SQLAlchemy()
>>> db.Time
<class 'sqlalchemy.sql.sqltypes.Time'>
>>> db.cast
<function cast at 0x7f60a3e89c80>
>>> from sqlalchemy import Time, cast
>>> Time
<class 'sqlalchemy.sql.sqltypes.Time'>
>>> cast
<function cast at 0x7f60a3e89c80>
>>> db.cast == cast and db.Time == Time
True