用于从 DAL 选择中排除某些值的查询或表达式
Posted
技术标签:
【中文标题】用于从 DAL 选择中排除某些值的查询或表达式【英文标题】:Query or Expression for excluding certain values from DAL selection 【发布时间】:2012-04-24 10:03:57 【问题描述】:我正在尝试从我的选择中排除带有名为 meta 的标签的帖子,作者:
meta_id = db(db.tags.name == "meta").select().first().id
not_meta = ~db.posts.tags.contains(meta_id)
posts=db(db.posts).select(not_meta)
但这些帖子仍然显示在我的选择中。
写这个表达式的正确方法是什么?
我的表格如下:
db.define_table('tags',
db.Field('name', 'string'),
db.Field('desc', 'text', default="")
)
db.define_table('posts',
db.Field('title', 'string'),
db.Field('message', 'text'),
db.Field('tags', 'list:reference tags'),
db.Field('time', 'datetime', default=datetime.utcnow())
)
我在 GAE 上使用 Web2Py 1.99.7,在 Python 2.7.2 上使用 High Replication DataStore
更新:
我刚刚按照@Anthony 的建议尝试了posts=db(not_meta).select()
,但它给了我一张带有以下 Traceback 的票:
Traceback (most recent call last):
File "E:\Programming\Python\web2py\gluon\restricted.py", line 205, in restricted
exec ccode in environment
File "E:/Programming/Python/web2py/applications/vote_up/controllers/default.py", line 391, in <module>
File "E:\Programming\Python\web2py\gluon\globals.py", line 173, in <lambda>
self._caller = lambda f: f()
File "E:/Programming/Python/web2py/applications/vote_up/controllers/default.py", line 8, in index
posts=db(not_meta).select()#orderby=settings.sel.posts, limitby=(0, settings.delta)
File "E:\Programming\Python\web2py\gluon\dal.py", line 7578, in select
return adapter.select(self.query,fields,attributes)
File "E:\Programming\Python\web2py\gluon\dal.py", line 3752, in select
(items, tablename, fields) = self.select_raw(query,fields,attributes)
File "E:\Programming\Python\web2py\gluon\dal.py", line 3709, in select_raw
filters = self.expand(query)
File "E:\Programming\Python\web2py\gluon\dal.py", line 3589, in expand
return expression.op(expression.first)
File "E:\Programming\Python\web2py\gluon\dal.py", line 3678, in NOT
raise SyntaxError, "Not suported %s" % first.op.__name__
SyntaxError: Not suported CONTAINS
更新 2:
由于 ~
目前没有使用 Datastore 处理 GAE,我使用以下方法作为临时解决方法:
meta = db.posts.tags.contains(settings.meta_id)
all=db(db.posts).select()#, limitby=(0, settings.delta)
meta=db(meta).select()
posts = []
i = 0
for post in all:
if i==settings.delta: break
if post in meta: continue
else:
posts.append(post)
i += 1
#settings.delta is an long integer to be used with limitby
【问题讨论】:
【参考方案1】:试试:
meta_id = db(db.tags.name == "meta").select().first().id
not_meta = ~db.posts.tags.contains(meta_id)
posts = db(not_meta).select()
首先,您的初始查询返回一个完整的 Row 对象,因此您只需提取“id”字段。其次,not_meta
是一个 Query 对象,所以它进入 db(not_meta)
内部来创建一个 Set 对象,定义要选择的记录集(select()
方法需要为每条记录返回一个字段列表,以及一个其他一些参数,例如orderby
、groupby
等)。
【讨论】:
真的很抱歉@Anthony,我在我的问题中错过了.id
,尽管我在我的代码中使用它。
我刚试过db(not_meta).select()
,但它给了我一个错误说<type 'exceptions.SyntaxError'> Not suported CONTAINS
您似乎在使用 Google App Engine。问题实际上出在~
(NOT) 运算符上——GAE 不支持它。
你说得对,没有~
也能正常工作。任何已知的解决方法?以上是关于用于从 DAL 选择中排除某些值的查询或表达式的主要内容,如果未能解决你的问题,请参考以下文章