首先这是一个很奇葩的需求,时间紧迫顺手胡写了一个,以后看看有没有好的思路

def and_(item_list):
return "%s:[%s]" % ("$and", ','.join(loop_func(item_list))) def or_(item_list):
return "%s:[%s]" % ("$or", ','.join(loop_func(item_list))) def lt(a, b):
return "%s<%s" % (a.name, b) def le(a, b):
return "%s<=%s" % (a.name, b) def ne(a, b):
return "%s!=%s" % (a.name, b) def ge(a, b):
return "%s>=%s" % (a.name, b) def eq(a, b):
return "%s=%s" % (a.name, b) def gt(a, b):
return "%s>%s" % (a.name, b) def in_op(a, b):
return '%s:{$in:%s}' % (a.name, b) def notin_op(a, b):
return '%s:{$nin:%s}' % (a.name, b) def desc_op(a):
return a def asc_op(a):
return a.asc() class ColumnOperators(object):
__slots__ = ['name'] def __init__(self, name):
self.name = name def __and__(self, other):
return self.operate(and_, other) def __or__(self, other):
return self.operate(or_, other) def __lt__(self, other):
return self.operate(lt, other) def __le__(self, other):
return self.operate(le, other) def __eq__(self, other):
return self.operate(eq, other) def __ne__(self, other):
return self.operate(ne, other) def __gt__(self, other):
return self.operate(gt, other) def __ge__(self, other):
return self.operate(ge, other) def operate(self, op, other):
return op(self, other) def in_(self, other):
return self.operate(in_op, other) def notin_(self, other):
return self.operate(notin_op, other) def desc(self):
return '{%s:1}' % self.name def asc(self):
return '{%s:-1}' % self.name dic = {'<': '$lt', '<=': '$lte', '=': '$eq', '>=': '$gte', '>': '$gt', '!=': '$ne'} def split_func(item, op):
split_item_list = item.strip().split(op) if len(split_item_list) != 2:
raise NotImplementedError("不支持同时两个及以上比较运算")
for split_item in split_item_list:
for key in dic:
if key in split_item:
raise NotImplementedError("不支持同时两个及以上比较运算")
return split_item_list, op def loop_func(item_list):
and_or_list = []
for item in item_list:
if ">=" in item:
split_item_list, op = split_func(item, ">=")
and_or_list.append("{%s:{%s:%s}}" % (split_item_list[0].strip(), dic[op], split_item_list[1].strip()))
elif "<=" in item:
split_item_list, op = split_func(item, "<=")
and_or_list.append("{%s:{%s:%s}}" % (split_item_list[0].strip(), dic[op], split_item_list[1].strip()))
elif "!=" in item:
split_item_list, op = split_func(item, ">=")
and_or_list.append("{%s:{%s:%s}}" % (split_item_list[0].strip(), dic[op], split_item_list[1].strip()))
elif "<" in item:
split_item_list, op = split_func(item, "<")
and_or_list.append("{%s:{%s:%s}}" % (split_item_list[0].strip(), dic[op], split_item_list[1].strip()))
elif "=" in item:
split_item_list, op = split_func(item, "=")
and_or_list.append("{%s:{%s:%s}}" % (split_item_list[0].strip(), dic[op], split_item_list[1].strip()))
elif ">" in item:
split_item_list, op = split_func(item, ">")
and_or_list.append("{%s:{%s:%s}}" % (split_item_list[0].strip(), dic[op], split_item_list[1].strip()))
else:
and_or_list.append('{%s}' % item)
return and_or_list def handle_op(item):
if ">=" in item:
split_item_list, op = split_func(item, ">=")
return "%s:{%s:%s}" % (split_item_list[0].strip(), dic[op], split_item_list[1].strip())
elif "<=" in item:
split_item_list, op = split_func(item, "<=")
return "%s:{%s:%s}" % (split_item_list[0].strip(), dic[op], split_item_list[1].strip())
elif "!=" in item:
split_item_list, op = split_func(item, "!=")
return "%s:{%s:%s}" % (split_item_list[0].strip(), dic[op], split_item_list[1].strip())
elif "<" in item:
split_item_list, op = split_func(item, "<")
return "%s:{%s:%s}" % (split_item_list[0].strip(), dic[op], split_item_list[1].strip())
elif "=" in item:
split_item_list, op = split_func(item, "=")
return "%s:{%s:%s}" % (split_item_list[0].strip(), dic[op], split_item_list[1].strip())
elif ">" in item:
split_item_list, op = split_func(item, ">")
return "%s:{%s:%s}" % (split_item_list[0].strip(), dic[op], split_item_list[1].strip())
else:
return item class Query(object):
__slots__ = ['_projection_list', '_query_criteria_list', '_exec_order'] def __init__(self, *entities):
self._projection_list = []
self._query_criteria_list = []
self._set_entities(*entities)
self._exec_order = [] def _set_entities(self, *entities):
if entities is not ():
for ent in list(entities):
self._projection_list.append(ent.name) def filter(self, *criterion):
if criterion is not ():
for cri in list(criterion):
self._query_criteria_list.append(handle_op(cri))
return self def order_by(self, standard):
if 'sort' not in self._exec_order:
self._exec_order.append({'sort': standard})
else:
raise RuntimeError("sort方法只能调用一次")
return self def limit(self, num):
if 'limit' not in self._exec_order:
self._exec_order.append({'limit': num})
else:
raise RuntimeError("limit方法只能调用一次")
return self def skip(self, num):
if 'skip' not in self._exec_order:
self._exec_order.append({'skip': num})
else:
raise RuntimeError("skip方法只能调用一次")
return self def query(*args):
return Query(*args) class Users(object):
id = ColumnOperators('id')
name = ColumnOperators('name')
age = ColumnOperators('age') def conditions(self): # 可以将这个方法写到类中,考虑到尽可能少的暴漏接口,就另外写了
dic = {}
if self._projection_list:
dic["columnStr"] = "{%s}" % (",".join(self._projection_list))
if self._query_criteria_list:
if len(self._query_criteria_list) == 1:
dic["condition"] = "{%s}" % (",".join(self._query_criteria_list))
else:
dic["condition"] = "{$and:[%s]}" % (",".join(['{%s}' % con for con in self._query_criteria_list]))
for i in self._exec_order:
dic.update(i)
return dic if __name__ == '__main__':
Query.conditions = property(conditions)
query_obj = query(
Users.id,
Users.name
).filter(
and_([Users.id > 5, Users.age > 20]),
or_([Users.name == 'Tom', Users.name == 'Jade'])
).order_by(Users.age.desc()).limit(3)
print(query_obj.conditions)

  

最新文章

  1. 【英语】Bingo口语笔记(38) - See系列
  2. [转载]jquery获取元素索引值index()方法:
  3. JVM参数说明(转)
  4. 基于visual Studio2013解决C语言竞赛题之1002字符打印
  5. Java与C#的比较学习
  6. (@WhiteTaken)UGUI中遇到的一些细碎的知识点
  7. Windows Phone 8.1开发:触控和指针事件2
  8. HTML基本文件, CSS基础
  9. App的前后台数据同步
  10. 图片人脸检测——Dlib版(四)
  11. Android项目实战(四十三):夜神模拟器
  12. zookeeper 学习 状态机复制的共识算法
  13. bootstrap-select 多选下拉框使用教程
  14. 最完整的mac安装caffe
  15. (DFS)展开字符串 -- hdu -- 1274
  16. 一个简单的代码生成器(T4文本模板运用)
  17. Centos 6.5 yum 安装Apache软件
  18. static笔记
  19. 如何让两个div并排,并且div要看得见边框
  20. Linux之 手动释放内存

热门文章

  1. 包、继承以及 LeetCode 27、28题
  2. 解决mysql时区与系统时区不一致问题。异常:The server time zone value &#39;&#214;&#208;&#185;&#250;&#177;&#234;&#215;&#188;&#202;&#177;&#188;&#228;&#39; is unrecognized or represents more than one time zone.
  3. Spring Boot Security 详解
  4. 由于服务主机:DCOM服务进程占用过多CPU,导致系统卡死
  5. HTTP概念解析
  6. Python 标准类库- 因特网协议于支持之UUID
  7. Linux- 常用命令, Vim编辑器操作
  8. 探索SQL Server元数据(一)
  9. 一个特殊的SQL Server阻塞案例分析
  10. RocketMQ三主三从二命名服务平滑版本升级实操