How to check the type of a document element (sub document vs list)? "ReqlServerCompileError: Variable name not found in: var_1"
How to check the type of a document element (sub document vs list)? "ReqlServerCompileError: Variable name not found in: var_1"
我通过提供一些额外的功能来扩展 RethinkDb API。
例如我简化了表达式
site_ids = r.table('periods')\
['regions']\
.concat_map(lambda row: row['sites'])\
['id']
至
site_ids = f['periods']\
.unwind('regions.sites.id')
使用能够解析嵌套文档元素路径的自定义 unwind
方法。如果给定路径中的项目是列表,则其条目与 concat_map
连接。否则使用 bracket
符号访问该项目:
def unwind(self, path):
items = path.split('.')
cursor = self._cursor
for item in items:
is_list = isinstance(cursor[item].run().next(), list)
if is_list:
cursor = cursor.concat_map(lambda row: row[item])
else:
cursor = cursor[item]
return self.wrap(self._f, cursor)
=> 如何改进类型检查以确定元素是否为列表? 检查不需要额外的 .run()
,它应该可以工作在主查询和子查询中。
我当前使用表达式
的实现
is_list = isinstance(cursor[item].run().next(), list)
在
等“主要查询”中工作正常
result = f['periods'] \
.unwind('regions.sites.plants.product.process.technologies')\
.populate_with('periods', 'technologies')\
.sum('specific_cost_per_year') \
.run()
它在子查询中不起作用,例如在映射函数中:
def period_mapper(period):
return {
'year': period['start'],
'site_ids': f.wrap(period).unwind('regions.sites.id')
}
f.table('periods')\
.map(period_mapper)\
.run()
我收到错误
rethinkdb.errors.ReqlServerCompileError: Variable name not found in:
var_1['regions']
^^^^^
因为我无法.run()
查询传递的变量参数“period”。
我尝试用 r.branch
替换 if-then-else 条件,但这没有帮助。
=> 如何更好地根据当前光标内容的类型选择运算符?
我选择的 class 包装 RethinkDb 游标的代码:
from rethinkdb.ast import RqlQuery
# needs to inherit from RqlQuery for the json serialization to work
class AbstractSelection(RqlQuery):
def __init__(self, f, cursor):
self._f = f
self._cursor = cursor
def __getitem__(self, identifier):
cursor = self._cursor[identifier]
return self.wrap(self._f, cursor)
def __repr__(self):
return self._cursor.__repr__()
def __str__(self):
return self._cursor.__str__()
def build(self):
return self._cursor.build()
@property
def _args(self): # required for json serialization
return self._cursor._args
@property
def optargs(self): # required for json serialization
return self._cursor.optargs
def wrap(self, r, cursor):
raise NotImplemented('Needs to be implemented by inheriting class')
def unwind(self, path):
items = path.split('.')
cursor = self._cursor
for item in items:
is_list = isinstance(cursor[item].run().next(), list)
if is_list:
cursor = cursor.concat_map(lambda row: row[item])
else:
cursor = cursor[item]
return self.wrap(self._f, cursor)
def pick(self, path, query):
return self.unwind(path).get(query)
def populate(self, collection_name, path):
return self.map(lambda identifier:
self._f[collection_name]
.pick(path, {'id': identifier})
)
def get(self, query):
cursor = self._cursor.filter(query)[0]
return self.wrap(self._f, cursor)
def to_array(self):
return [item for item in self._cursor]
我设法将 type_of
与 branch
结合使用。使用括号符号 returns a STREAM
访问项目,在使用 type_of
检查 'ARRAY' 类型之前,我必须使用 [0] 获取第一个项目。如果 属性 不是数组,这也有效:
def unwind(self, path):
items = path.split('.')
cursor = self._cursor
r = self._f._r
for item in items:
cursor = r.branch(
cursor[item][0].type_of() == 'ARRAY',
cursor.concat_map(lambda row: row[item]),
cursor[item]
)
return self.wrap(self._f, cursor)
我通过提供一些额外的功能来扩展 RethinkDb API。
例如我简化了表达式
site_ids = r.table('periods')\
['regions']\
.concat_map(lambda row: row['sites'])\
['id']
至
site_ids = f['periods']\
.unwind('regions.sites.id')
使用能够解析嵌套文档元素路径的自定义 unwind
方法。如果给定路径中的项目是列表,则其条目与 concat_map
连接。否则使用 bracket
符号访问该项目:
def unwind(self, path):
items = path.split('.')
cursor = self._cursor
for item in items:
is_list = isinstance(cursor[item].run().next(), list)
if is_list:
cursor = cursor.concat_map(lambda row: row[item])
else:
cursor = cursor[item]
return self.wrap(self._f, cursor)
=> 如何改进类型检查以确定元素是否为列表? 检查不需要额外的 .run()
,它应该可以工作在主查询和子查询中。
我当前使用表达式
的实现is_list = isinstance(cursor[item].run().next(), list)
在
等“主要查询”中工作正常result = f['periods'] \
.unwind('regions.sites.plants.product.process.technologies')\
.populate_with('periods', 'technologies')\
.sum('specific_cost_per_year') \
.run()
它在子查询中不起作用,例如在映射函数中:
def period_mapper(period):
return {
'year': period['start'],
'site_ids': f.wrap(period).unwind('regions.sites.id')
}
f.table('periods')\
.map(period_mapper)\
.run()
我收到错误
rethinkdb.errors.ReqlServerCompileError: Variable name not found in:
var_1['regions']
^^^^^
因为我无法.run()
查询传递的变量参数“period”。
我尝试用 r.branch
替换 if-then-else 条件,但这没有帮助。
=> 如何更好地根据当前光标内容的类型选择运算符?
我选择的 class 包装 RethinkDb 游标的代码:
from rethinkdb.ast import RqlQuery
# needs to inherit from RqlQuery for the json serialization to work
class AbstractSelection(RqlQuery):
def __init__(self, f, cursor):
self._f = f
self._cursor = cursor
def __getitem__(self, identifier):
cursor = self._cursor[identifier]
return self.wrap(self._f, cursor)
def __repr__(self):
return self._cursor.__repr__()
def __str__(self):
return self._cursor.__str__()
def build(self):
return self._cursor.build()
@property
def _args(self): # required for json serialization
return self._cursor._args
@property
def optargs(self): # required for json serialization
return self._cursor.optargs
def wrap(self, r, cursor):
raise NotImplemented('Needs to be implemented by inheriting class')
def unwind(self, path):
items = path.split('.')
cursor = self._cursor
for item in items:
is_list = isinstance(cursor[item].run().next(), list)
if is_list:
cursor = cursor.concat_map(lambda row: row[item])
else:
cursor = cursor[item]
return self.wrap(self._f, cursor)
def pick(self, path, query):
return self.unwind(path).get(query)
def populate(self, collection_name, path):
return self.map(lambda identifier:
self._f[collection_name]
.pick(path, {'id': identifier})
)
def get(self, query):
cursor = self._cursor.filter(query)[0]
return self.wrap(self._f, cursor)
def to_array(self):
return [item for item in self._cursor]
我设法将 type_of
与 branch
结合使用。使用括号符号 returns a STREAM
访问项目,在使用 type_of
检查 'ARRAY' 类型之前,我必须使用 [0] 获取第一个项目。如果 属性 不是数组,这也有效:
def unwind(self, path):
items = path.split('.')
cursor = self._cursor
r = self._f._r
for item in items:
cursor = r.branch(
cursor[item][0].type_of() == 'ARRAY',
cursor.concat_map(lambda row: row[item]),
cursor[item]
)
return self.wrap(self._f, cursor)