def get_query_mailbox(self, query):
nofield = True
tablename = None
attr = query
while nofield:
if hasattr(attr, "first"):
attr = attr.first
if isinstance(attr, Field):
return attr.tablename
elif isinstance(attr, Query):
pass
else:
return None
else:
return None
return tablename
python类Query()的实例源码
def test_Query_type(self):
"""
L{db.Query} instances get converted to lists ..
"""
q = models.EmptyModel.all()
self.assertTrue(isinstance(q, db.Query))
self.assertEncodes(q, b'\n\x00\x00\x00\x00', encoding=pyamf.AMF0)
self.assertEncodes(q, b'\t\x01\x01', encoding=pyamf.AMF3)
def all(cls):
"""Get query for all Blobs associated with application.
Returns:
A db.Query object querying over BlobInfo's datastore kind.
"""
return db.Query(model_class=cls, namespace='')
def _IsNdbQuery(query):
return ndb is not None and isinstance(query, ndb.Query)
def filter_query(self, query, filters=None):
"""Add query filter to restrict to this key range.
Args:
query: A db.Query or ndb.Query instance.
filters: optional list of filters to apply to the query. Each filter is
a tuple: (<property_name_as_str>, <query_operation_as_str>, <value>).
User filters are applied first.
Returns:
The input query restricted to this key range.
"""
if ndb is not None:
if _IsNdbQuery(query):
return self.filter_ndb_query(query, filters=filters)
assert not _IsNdbQuery(query)
if filters:
for f in filters:
query.filter("%s %s" % (f[0], f[1]), f[2])
if self.include_start:
start_comparator = ">="
else:
start_comparator = ">"
if self.include_end:
end_comparator = "<="
else:
end_comparator = "<"
if self.key_start:
query.filter("__key__ %s" % start_comparator, self.key_start)
if self.key_end:
query.filter("__key__ %s" % end_comparator, self.key_end)
return query
def filter_ndb_query(self, query, filters=None):
"""Add query filter to restrict to this key range.
Args:
query: An ndb.Query instance.
filters: optional list of filters to apply to the query. Each filter is
a tuple: (<property_name_as_str>, <query_operation_as_str>, <value>).
User filters are applied first.
Returns:
The input query restricted to this key range.
"""
assert _IsNdbQuery(query)
if filters:
for f in filters:
query = query.filter(ndb.FilterNode(*f))
if self.include_start:
start_comparator = ">="
else:
start_comparator = ">"
if self.include_end:
end_comparator = "<="
else:
end_comparator = "<"
if self.key_start:
query = query.filter(ndb.FilterNode("__key__",
start_comparator,
self.key_start))
if self.key_end:
query = query.filter(ndb.FilterNode("__key__",
end_comparator,
self.key_end))
return query
def filter_datastore_query(self, query, filters=None):
"""Add query filter to restrict to this key range.
Args:
query: A datastore.Query instance.
filters: optional list of filters to apply to the query. Each filter is
a tuple: (<property_name_as_str>, <query_operation_as_str>, <value>).
User filters are applied first.
Returns:
The input query restricted to this key range.
"""
assert isinstance(query, datastore.Query)
if filters:
for f in filters:
query.update({"%s %s" % (f[0], f[1]): f[2]})
if self.include_start:
start_comparator = ">="
else:
start_comparator = ">"
if self.include_end:
end_comparator = "<="
else:
end_comparator = "<"
if self.key_start:
query.update({"__key__ %s" % start_comparator: self.key_start})
if self.key_end:
query.update({"__key__ %s" % end_comparator: self.key_end})
return query
def make_directed_ndb_query(self, kind_class, keys_only=False):
"""Construct an NDB query for this key range, including the scan direction.
Args:
kind_class: An ndb.Model subclass.
keys_only: bool, default False, use keys_only on Query?
Returns:
An ndb.Query instance.
Raises:
KeyRangeError: if self.direction is not in (KeyRange.ASC, KeyRange.DESC).
"""
assert issubclass(kind_class, ndb.Model)
if keys_only:
default_options = ndb.QueryOptions(keys_only=True)
else:
default_options = None
query = kind_class.query(app=self._app,
namespace=self.namespace,
default_options=default_options)
query = self.filter_ndb_query(query)
if self.__get_direction(True, False):
query = query.order(kind_class._key)
else:
query = query.order(-kind_class._key)
return query
def all(cls):
"""Get query for all Blobs associated with application.
Returns:
A db.Query object querying over BlobInfo's datastore kind.
"""
return db.Query(model_class=cls, namespace='')
def _IsNdbQuery(query):
return ndb is not None and isinstance(query, ndb.Query)
def filter_query(self, query, filters=None):
"""Add query filter to restrict to this key range.
Args:
query: A db.Query or ndb.Query instance.
filters: optional list of filters to apply to the query. Each filter is
a tuple: (<property_name_as_str>, <query_operation_as_str>, <value>).
User filters are applied first.
Returns:
The input query restricted to this key range.
"""
if ndb is not None:
if _IsNdbQuery(query):
return self.filter_ndb_query(query, filters=filters)
assert not _IsNdbQuery(query)
if filters:
for f in filters:
query.filter("%s %s" % (f[0], f[1]), f[2])
if self.include_start:
start_comparator = ">="
else:
start_comparator = ">"
if self.include_end:
end_comparator = "<="
else:
end_comparator = "<"
if self.key_start:
query.filter("__key__ %s" % start_comparator, self.key_start)
if self.key_end:
query.filter("__key__ %s" % end_comparator, self.key_end)
return query
def filter_ndb_query(self, query, filters=None):
"""Add query filter to restrict to this key range.
Args:
query: An ndb.Query instance.
filters: optional list of filters to apply to the query. Each filter is
a tuple: (<property_name_as_str>, <query_operation_as_str>, <value>).
User filters are applied first.
Returns:
The input query restricted to this key range.
"""
assert _IsNdbQuery(query)
if filters:
for f in filters:
query = query.filter(ndb.FilterNode(*f))
if self.include_start:
start_comparator = ">="
else:
start_comparator = ">"
if self.include_end:
end_comparator = "<="
else:
end_comparator = "<"
if self.key_start:
query = query.filter(ndb.FilterNode("__key__",
start_comparator,
self.key_start))
if self.key_end:
query = query.filter(ndb.FilterNode("__key__",
end_comparator,
self.key_end))
return query
def filter_datastore_query(self, query, filters=None):
"""Add query filter to restrict to this key range.
Args:
query: A datastore.Query instance.
filters: optional list of filters to apply to the query. Each filter is
a tuple: (<property_name_as_str>, <query_operation_as_str>, <value>).
User filters are applied first.
Returns:
The input query restricted to this key range.
"""
assert isinstance(query, datastore.Query)
if filters:
for f in filters:
query.update({"%s %s" % (f[0], f[1]): f[2]})
if self.include_start:
start_comparator = ">="
else:
start_comparator = ">"
if self.include_end:
end_comparator = "<="
else:
end_comparator = "<"
if self.key_start:
query.update({"__key__ %s" % start_comparator: self.key_start})
if self.key_end:
query.update({"__key__ %s" % end_comparator: self.key_end})
return query
def make_directed_ndb_query(self, kind_class, keys_only=False):
"""Construct an NDB query for this key range, including the scan direction.
Args:
kind_class: An ndb.Model subclass.
keys_only: bool, default False, use keys_only on Query?
Returns:
An ndb.Query instance.
Raises:
KeyRangeError: if self.direction is not in (KeyRange.ASC, KeyRange.DESC).
"""
assert issubclass(kind_class, ndb.Model)
if keys_only:
default_options = ndb.QueryOptions(keys_only=True)
else:
default_options = None
query = kind_class.query(app=self._app,
namespace=self.namespace,
default_options=default_options)
query = self.filter_ndb_query(query)
if self.__get_direction(True, False):
query = query.order(kind_class._key)
else:
query = query.order(-kind_class._key)
return query
def expand(self, expression, field_type=None):
if isinstance(expression, Field):
out = '%s.%s' % (expression.table._tablename, expression.name)
if field_type == 'string' and not expression.type in (
'string','text','json','password'):
out = 'CAST(%s AS %s)' % (out, self.types['text'])
return out
elif isinstance(expression, (Expression, Query)):
first = expression.first
second = expression.second
op = expression.op
optional_args = expression.optional_args or {}
if not second is None:
out = op(first, second, **optional_args)
elif not first is None:
out = op(first,**optional_args)
elif isinstance(op, str):
if op.endswith(';'):
op=op[:-1]
out = '(%s)' % op
else:
out = op()
return out
elif field_type:
return str(self.represent(expression,field_type))
elif isinstance(expression,(list,tuple)):
return ','.join(self.represent(item,field_type) \
for item in expression)
elif isinstance(expression, bool):
return '1' if expression else '0'
else:
return str(expression)
def tables(self, *queries):
tables = set()
for query in queries:
if isinstance(query, Field):
tables.add(query.tablename)
elif isinstance(query, (Expression, Query)):
if not query.first is None:
tables = tables.union(self.tables(query.first))
if not query.second is None:
tables = tables.union(self.tables(query.second))
return list(tables)
def NOT(self,first):
nops = { self.EQ: self.NE,
self.NE: self.EQ,
self.LT: self.GE,
self.GT: self.LE,
self.LE: self.GT,
self.GE: self.LT}
if not isinstance(first,Query):
raise SyntaxError("Not suported")
nop = nops.get(first.op,None)
if not nop:
raise SyntaxError("Not suported %s" % first.op.__name__)
first.op = nop
return self.expand(first)
def _select(self,query,fields,attributes):
if not isinstance(query,Query):
raise SyntaxError("Not Supported")
for key in set(attributes.keys())-SELECT_ARGS:
raise SyntaxError('invalid select attribute: %s' % key)
new_fields=[]
for item in fields:
if isinstance(item,SQLALL):
new_fields += item._table
else:
new_fields.append(item)
def uid(fd):
return fd=='id' and '_id' or fd
def get(row,fd):
return fd=='id' and long(row['_id']) or row.get(fd,None)
fields = new_fields
tablename = self.get_table(query)
fieldnames = [f.name for f in (fields or self.db[tablename])]
colnames = ['%s.%s' % (tablename,k) for k in fieldnames]
fields = ','.join(['%s.%s' % (tablename,uid(f)) for f in fieldnames])
fn="(function(%(t)s){if(%(query)s)emit(%(order)s,[%(fields)s]);})" %\
dict(t=tablename,
query=self.expand(query),
order='%s._id' % tablename,
fields=fields)
return fn, colnames
def update(self,tablename,query,fields):
if not isinstance(query,Query):
raise SyntaxError("Not Supported")
if query.first.type=='id' and query.op==self.EQ:
id = query.second
tablename = query.first.tablename
ctable = self.connection[tablename]
try:
doc = ctable[str(id)]
for key,value in fields:
doc[key.name] = self.represent(value,self.db[tablename][key.name].type)
ctable.save(doc)
return 1
except couchdb.http.ResourceNotFound:
return 0
else:
tablename = self.get_table(query)
rows = self.select(query,[self.db[tablename]._id],{})
ctable = self.connection[tablename]
table = self.db[tablename]
for row in rows:
doc = ctable[str(row.id)]
for key,value in fields:
doc[key.name] = self.represent(value,table[key.name].type)
ctable.save(doc)
return len(rows)
def count(self,query,distinct=None):
if distinct:
raise RuntimeError("COUNT DISTINCT not supported")
if not isinstance(query,Query):
raise SyntaxError("Not Supported")
tablename = self.get_table(query)
rows = self.select(query,[self.db[tablename]._id],{})
return len(rows)