概述
查询字符串:
query = '{ "ord_date": { "$gte": { "$date": "2020-03-20T" } } }'
使用json_util.loads将查询字符串转换成字典时出错。
from bson import json_util
query = '{ "ord_date": { "$gte": { "$date": "2020-03-20" } } }'
try:
query = json_util.loads(query)
except Exception as e:
print(e)
打印出来的错误:
time data '2020-03' does not match format '%Y-%m-%dT%H:%M:%S'
需求:希望json_util.loads能解析'%Y-%m-%d'这样的date类型。
解决:
改写json_util的_parse_canonical_datetime,对应下面代码中的_parse_canonical_datetime_new
使用dateutil模块的parser.parse方法对字符串进行解析,随后 使用datetime.datetime.strftime方法将datetime类型转换成"%Y-%m-%dT%H:%M:%SZ"格式的字符串。
def loads_new(s, *args, **kwargs):
"""Helper function that wraps :func:`json.loads`.
Automatically passes the object_hook for BSON type conversion.
Raises ``TypeError``, ``ValueError``, ``KeyError``, or
:exc:`~bson.errors.InvalidId` on invalid MongoDB Extended JSON.
:Parameters:
- `json_options`: A :class:`JSONOptions` instance used to modify the
decoding of MongoDB Extended JSON types. Defaults to
:const:`DEFAULT_JSON_OPTIONS`.
.. versionchanged:: 3.5
Parses Relaxed and Canonical Extended JSON as well as PyMongo's legacy
format. Now raises ``TypeError`` or ``ValueError`` when parsing JSON
type wrappers with values of the wrong type or any extra keys.
.. versionchanged:: 3.4
Accepts optional parameter `json_options`. See :class:`JSONOptions`.
"""
json_options = kwargs.pop("json_options", DEFAULT_JSON_OPTIONS)
kwargs["object_pairs_hook"] = lambda pairs: object_pairs_hook(
pairs, json_options)
return json.loads(s, *args, **kwargs)
def object_pairs_hook(pairs, json_options=DEFAULT_JSON_OPTIONS):
return object_hook_new(json_options.document_class(pairs), json_options)
def object_hook_new(dct, json_options=DEFAULT_JSON_OPTIONS):
if "$date" in dct:
return _parse_canonical_datetime_new(dct, json_options)
else:
return object_hook(dct, json_options=DEFAULT_JSON_OPTIONS)
def _parse_canonical_datetime_new(doc, json_options):
"""Decode a JSON datetime to python datetime.datetime."""
dtm = doc["$date"]
parse_date = parser.parse(dtm)
dtm = datetime.datetime.strftime(parse_date, "%Y-%m-%dT%H:%M:%SZ")
if len(doc) != 1:
raise TypeError('Bad $date, extra field(s): %s' % (doc,))
# mongoexport 2.6 and newer
if isinstance(dtm, string_type):
# Parse offset
if dtm[-1] == 'Z':
dt = dtm[:-1]
offset = 'Z'
elif dtm[-6] in ('+', '-') and dtm[-3] == ':':
# (+|-)HH:MM
dt = dtm[:-6]
offset = dtm[-6:]
elif dtm[-5] in ('+', '-'):
# (+|-)HHMM
dt = dtm[:-5]
offset = dtm[-5:]
elif dtm[-3] in ('+', '-'):
# (+|-)HH
dt = dtm[:-3]
offset = dtm[-3:]
else:
dt = dtm
offset = ''
# Parse the optional factional seconds portion.
dot_index = dt.rfind('.')
microsecond = 0
if dot_index != -1:
microsecond = int(float(dt[dot_index:]) * 1000000)
dt = dt[:dot_index]
aware = datetime.datetime.strptime(
dt, "%Y-%m-%dT%H:%M:%S").replace(microsecond=microsecond,
tzinfo=utc)
if offset and offset != 'Z':
if len(offset) == 6:
hours, minutes = offset[1:].split(':')
secs = (int(hours) * 3600 + int(minutes) * 60)
elif len(offset) == 5:
secs = (int(offset[1:3]) * 3600 + int(offset[3:]) * 60)
elif len(offset) == 3:
secs = int(offset[1:3]) * 3600
if offset[0] == "-":
secs *= -1
aware = aware - datetime.timedelta(seconds=secs)
if json_options.tz_aware:
if json_options.tzinfo:
aware = aware.astimezone(json_options.tzinfo)
return aware
else:
return aware.replace(tzinfo=None)
return bson._millis_to_datetime(int(dtm), json_options)
最后
以上就是精明小丸子为你收集整理的pymongo date类型处理的全部内容,希望文章能够帮你解决pymongo date类型处理所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复