Permalink
Browse files

Adding a count() finalizing statement to queries

  • Loading branch information...
stevearc committed Mar 11, 2014
1 parent 6e494b3 commit bf3261c5c7bf49ffa4007f59104984a24168c0b8
Showing with 61 additions and 2 deletions.
  1. +10 −1 doc/topics/queries.rst
  2. +32 −0 flywheel/query.py
  3. +9 −1 tests/test_queries.py
  4. +10 −0 tests/test_scan.py
@@ -38,7 +38,7 @@ memory at the same time.
for tweet in all_tweets:
retweets += tweet.retweets
there are two finalizing statements that retrieve a single item:
There are two finalizing statements that retrieve a single item:
:meth:`~flywheel.engine.Query.first` and :meth:`~flywheel.engine.Query.one`.
Calling :meth:`~flywheel.engine.Query.first` will return the first element of
the results, or None if there are no results. Calling
@@ -55,6 +55,15 @@ results it will raise a :class:`ValueError`.
tweet = engine.query(Tweet).filter(Tweet.userid == 'abc123',
Tweet.id == '1234').one()
There is one more finalizing statement: :meth:`~flywheel.engine.Query.count`.
This will return the number of results that matched the query, instead of
returning the results themselves.
.. code-block:: python
# Get the number of tweets made by user abc123
num = engine.query(Tweet).filter(Tweet.userid == 'abc123').count()
You can set a :meth:`~flywheel.engine.Query.limit` on a query to limit the
number of results it returns:
@@ -48,6 +48,10 @@ def gen(self, desc=False, consistent=False, attributes=None):
List of fields to retrieve from dynamo. If supplied, gen() will
iterate over dicts instead of model objects.
Returns
-------
results : generator
"""
kwargs = self.condition.query_kwargs(self.model)
if attributes is not None:
@@ -78,10 +82,26 @@ def all(self, desc=False, consistent=False, attributes=None):
List of fields to retrieve from dynamo. If supplied, returns dicts
instead of model objects.
Returns
-------
results : list
"""
return list(self.gen(desc=desc, consistent=consistent,
attributes=attributes))
def count(self):
"""
Find the number of elements the match this query
Returns
-------
count : int
"""
kwargs = self.condition.query_kwargs(self.model)
return self.dynamo.query(self.tablename, count=True, **kwargs)
def first(self, desc=False, consistent=False, attributes=None):
"""
Return the first result of the query, or None if no results
@@ -96,6 +116,10 @@ def first(self, desc=False, consistent=False, attributes=None):
List of fields to retrieve from dynamo. If supplied, returns dicts
instead of model objects.
Returns
-------
result : :class:`~flywheel.models.Model` or None
"""
self.limit(1)
for result in self.gen(desc=desc, consistent=consistent,
@@ -116,6 +140,10 @@ def one(self, consistent=False, attributes=None):
List of fields to retrieve from dynamo. If supplied, returns dicts
instead of model objects.
Returns
-------
result : :class:`~flywheel.models.Model`
Raises
------
exc : ValueError
@@ -219,5 +247,9 @@ def gen(self, attributes=None, desc=False, consistent=False):
else:
yield self.model.ddb_load_(self.engine, result)
def count(self):
kwargs = self.condition.scan_kwargs()
return self.dynamo.scan(self.tablename, count=True, **kwargs)
def index(self, name):
raise TypeError("Scan cannot use an index!")
@@ -71,7 +71,7 @@ def test_one(self):
self.assertEquals(result, u)
def test_one_many(self):
""" If no results, first() returns None """
""" If many results, one() raises ValueError """
u = User(id='a', name='Adam')
u2 = User(id='a', name='Aaron')
self.engine.save([u, u2])
@@ -83,6 +83,14 @@ def test_one_none(self):
with self.assertRaises(ValueError):
self.engine(User).filter(id='a').one()
def test_count(self):
""" Can return a count instead of the models """
u = User(id='a', name='Adam')
u2 = User(id='a', name='Aaron')
self.engine.save([u, u2])
count = self.engine(User).filter(id='a').count()
self.assertEqual(count, 2)
def test_iter(self):
""" Queries can iterate over items """
u = User(id='a', name='Adam')
@@ -39,6 +39,16 @@ def test_gen(self):
self.assertTrue(u in results)
self.assertTrue(u2 in results)
def test_count(self):
""" Can return a count instead of the models """
u = User(id='a', name='Adam')
u2 = User(id='b', name='Billy')
self.engine.save([u, u2])
count = self.engine.scan(User).count()
self.assertEqual(count, 2)
count = self.engine.scan(User).filter(id='a').count()
self.assertEqual(count, 1)
def test_iter(self):
""" Scan can iterate over items """
u = User(id='a', name='Adam')

0 comments on commit bf3261c

Please sign in to comment.