美文网首页
pymongo 修改源码支持时间过滤查询

pymongo 修改源码支持时间过滤查询

作者: hugoren | 来源:发表于2018-11-30 11:50 被阅读0次

    背景

    pymongo 版本3.7.2
    不支持string类型的时间过滤查询
    为什么是string类型呢
    从界面传回的值就是string类型

    image.png

    研究发现pymongo支持datetime和参数形式

    datetime

    str_time = "2018-11-16 09:53:08"
    obj_datetime = datetime.datetime.strptime(str_time, "%Y-%m-%d %H:%M:%S")
    t = {"$gt": obj_datetime}
    tt = {"createTime":t}
    sql = 'xxx.find({0})'.format(tt)
    

    参数

    image.png

    解决方案的思考

    1.在后端接收到查询语句时间,把string的时间转换成datetime
    2.修改pymongo的源码

    尝试了第一种方案未果

    替换时候,datetime对象替换不了str,都是报异常 datetime转str或 + str类型异常。
    尝试替换的三种写法
    源码在cursor.py的第140行左右,这种改法仅对find查询有效。

    sql = 'xxx.find({"createTime":{"$gt":"2018-11-16 09:53:08", "$lte":"2018-11-18 09:53:08"}})'
    import re
    import datetime
    from flashtext import KeywordProcessor
    
    kp = KeywordProcessor()
    compile_datetime = re.compile(r"(\d{4}-\d{1,2}-\d{1,2}\s\d{1,2}:\d{1,2}:\d{1,2})")
    datetime_list = compile_datetime.findall(sql)
    if datetime_list:
        datetime_dict = {}
        for i in datetime_list:
            obj_datetime = datetime.datetime.strptime(i, "%Y-%m-%d %H:%M:%S")
            datetime_dict[i] = obj_datetime
    
    # dt = datetime.datetime(2018, 11, 11, 11, 11)
    str_time = "2018-11-16 09:53:08"
    dt = datetime.datetime.strptime(str_time, "%Y-%m-%d %H:%M:%S")
    
    #kp
    kp.add_keyword("2018-11-18 09:53:08", dt)
    new_sql = kp.replace_keywords(sql)
    print(new_sql)
    
    #re
    # new_sql = re.sub(r"2018-11-16 09:53:08", dt, sql)
    # print(new_sql)
    
    # replace
    # new_sql = sql.replace("2018-11-16 09:53:08", dt)
    # print(new_sql)
    
    

    find类型的修改源码cursor.py 142行

    cursor.py 的filter是字典的形式

     # 打个patch, 把str的时间str_time = "2018-11-16 09:53:08"转换成datetime对象
            try:
                import re
                import datetime
                if isinstance(filter, (dict)):
                    compile_datetime = re.compile(r"(\d{4}-\d{1,2}-\d{1,2}\s\d{1,2}:\d{1,2}:\d{1,2})")
                    filter = {k1: {k2: datetime.datetime.strptime(v2, "%Y-%m-%d %H:%M:%S") if compile_datetime.findall(v2) else v2 for k2, v2 in v1.items()} if isinstance(v1, (dict)) else v1 for k1, v1 in filter.items()}
                    # for i, j in filter.items():
                    #     if isinstance(j, (dict)):
                    #         for k, l in j.items():
                    #             compile_datetime = re.compile(r"(\d{4}-\d{1,2}-\d{1,2}\s\d{1,2}:\d{1,2}:\d{1,2})")
                    #             datetime_list = compile_datetime.findall(l)
                    #             if datetime_list:
                    #                 obj_datetime = datetime.datetime.strptime(datetime_list[0], "%Y-%m-%d %H:%M:%S")
                    #                 l = obj_datetime
                    # filter={}
            except Exception as e:
                print(e)
    

    两种写法,一种是字典推导式,另一种是分解的方式,相对于第一种,第二种比较清晰了然


    image.png

    aggregate类型的修改源码collection.py 2392行

    # 打个patch转换datetime时间类型
           import re
           import datetime
           compile_datetime = re.compile(r"(\d{4}-\d{1,2}-\d{1,2}\s\d{1,2}:\d{1,2}:\d{1,2})")
    
           pipeline_example = [
               {'$match': {'sourceType': 4, 'depositMoney': {'$gte': 400}, 'startDate': {"$gte": "2019-04-04 00:00:00"}}}]
           # datetime.datetime.strptime(i, "%Y-%m-%d %H:%M:%S")
           try:
               pipeline = [{k: {
               m: {x: datetime.datetime.strptime(y, "%Y-%m-%d %H:%M:%S") if compile_datetime.findall(str(y)) else y for x, y in
                   n.items()} if isinstance(n, (dict,)) else datetime.datetime.strptime(n,
                                                                                        "%Y-%m-%d %H:%M:%S") if compile_datetime.findall(
                   str(n)) else n for m, n in v.items()} for k, v in i.items()} for i in pipeline]
           except Exception as e:
               print("aggregate 时间类型转换失败, 原因:{}".format(str(e)))
    

    相关文章

      网友评论

          本文标题:pymongo 修改源码支持时间过滤查询

          本文链接:https://www.haomeiwen.com/subject/jpnccqtx.html