【发布时间】:2020-02-23 23:12:40
【问题描述】:
我正在尝试实现一个标签过滤机制,其中项目可以有任意数量的与之关联的标签,并且我希望能够找到具有任何或所有请求标签的项目。
我的架构是这样的:
class Item(db.Entity):
tags = orm.Set("ItemTag")
class ItemTag(db.Entity):
item = orm.Required(Item)
tag = orm.Required(str)
orm.composite_key(item, tag)
orm.composite_key(tag, item)
我可以使用单个标签轻松过滤现有查询:
def filter_query_tag(query, tag:str):
return orm.select(i for i in query for t in i.tags if t.key == tag)
而且我可以轻松找到带有 任何 标记的项目:
def filter_query_any_tag(query, tags:typing.Union(set,list,tuple)):
return orm.select(i for i in query for t in i.tags if t.key in tags)
但尝试构建查找所有标签的查询会引发错误:
def filter_query_all_tags(query, tags:typing.Union(set,list,tuple)):
for tag in tags:
query = orm.select(i for i in query for t in i.tags if t.key == tag)
return query
结果:
File "/Users/fluffy/.local/share/virtualenvs/Publ-FUB3ZG92/lib/python3.7/site-packages/pony/orm/core.py", line 5562, in select
return make_query(args, frame_depth=cut_traceback_depth+1)
File "/Users/fluffy/.local/share/virtualenvs/Publ-FUB3ZG92/lib/python3.7/site-packages/pony/orm/core.py", line 5558, in make_query
return Query(code_key, tree.code, globals, locals, cells, left_join)
File "/Users/fluffy/.local/share/virtualenvs/Publ-FUB3ZG92/lib/python3.7/site-packages/pony/orm/core.py", line 5717, in __init__
translator = translator_cls(tree_copy, None, code_key, filter_num, extractors, vars, vartypes.copy(), left_join=left_join)
File "/Users/fluffy/.local/share/virtualenvs/Publ-FUB3ZG92/lib/python3.7/site-packages/pony/orm/sqltranslation.py", line 222, in __init__
translator.init(tree, parent_translator, code_key, filter_num, extractors, vars, vartypes, left_join, optimize)
File "/Users/fluffy/.local/share/virtualenvs/Publ-FUB3ZG92/lib/python3.7/site-packages/pony/orm/sqltranslation.py", line 396, in init
tableref = translator.sqlquery.add_tableref(name_path, parent_tableref, attr)
File "/Users/fluffy/.local/share/virtualenvs/Publ-FUB3ZG92/lib/python3.7/site-packages/pony/orm/sqltranslation.py", line 1211, in add_tableref
assert name_path not in sqlquery.tablerefs
AssertionError
据推测,问题在于将多个连接名称映射到同一个表时存在问题,这可能是 ponyorm 中的一个错误。但是,我怀疑可能有更好的方法来构建查询,而无需首先执行多个连接和过滤器。
我尝试使用orm.left_join 而不是orm.select,如下所示:
def filter_query_all_tags(query, tags:typing.Union(set,list,tuple)):
for tag in tags:
query = orm.left_join(i for i in query for t in i.tags if t.key == tag)
return query
在这种情况下,我可以同时过滤 两个 标签,但如果我添加第三个标签,我会得到:
File "/Users/fluffy/.local/share/virtualenvs/Publ-FUB3ZG92/lib/python3.7/site-packages/pony/orm/core.py", line 5566, in left_join
return make_query(args, frame_depth=cut_traceback_depth+1, left_join=True)
File "/Users/fluffy/.local/share/virtualenvs/Publ-FUB3ZG92/lib/python3.7/site-packages/pony/orm/core.py", line 5558, in make_query
return Query(code_key, tree.code, globals, locals, cells, left_join)
File "/Users/fluffy/.local/share/virtualenvs/Publ-FUB3ZG92/lib/python3.7/site-packages/pony/orm/core.py", line 5717, in __init__
translator = translator_cls(tree_copy, None, code_key, filter_num, extractors, vars, vartypes.copy(), left_join=left_join)
File "/Users/fluffy/.local/share/virtualenvs/Publ-FUB3ZG92/lib/python3.7/site-packages/pony/orm/sqltranslation.py", line 222, in __init__
translator.init(tree, parent_translator, code_key, filter_num, extractors, vars, vartypes, left_join, optimize)
File "/Users/fluffy/.local/share/virtualenvs/Publ-FUB3ZG92/lib/python3.7/site-packages/pony/orm/sqltranslation.py", line 343, in init
names, try_extend_prev_query=not i)
File "/Users/fluffy/.local/share/virtualenvs/Publ-FUB3ZG92/lib/python3.7/site-packages/pony/orm/sqltranslation.py", line 598, in process_query_qual
subquery_ast = prev_translator.construct_subquery_ast(prev_limit, prev_offset, aliases=aliases)
File "/Users/fluffy/.local/share/virtualenvs/Publ-FUB3ZG92/lib/python3.7/site-packages/pony/orm/sqltranslation.py", line 625, in construct_subquery_ast
assert not star and len(aliases) == len(select_ast) - 1
AssertionError
在 ponyorm 中是否有一个原始或惯用的表达式允许我指定集合的 所有 值必须存在于任何给定 Item 的 ItemTag 值中?
【问题讨论】:
-
AssertionError 表示您遇到了意外行为。你介意为这个案例打开一个问题吗? github.com/ponyorm/pony/issues/new
-
@sashaaero 已打开 github.com/ponyorm/pony/issues/488,谢谢提醒