Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,24 @@ Bug Fixes
* cqlengine: class.MultipleObjectsReturned has DoesNotExist as base class (PYTHON-489)
* cqlengine: Typo in cqlengine UserType __len__ breaks attribute assignment (PYTHON-502)


Other
-----

* cqlengine: a major improvement on queryset has been introduced. It
is a lot more efficient to iterate large datasets: the rows are
now fetched on demand using the driver pagination.

* cqlengine: the queryset len() and count() behaviors have changed. It
now executes a "SELECT COUNT(*)" of the query rather than returning
the size of the internal result_cache (loaded rows). On large
queryset, you might want to avoid using them due to the performance
cost. Note that trying to access objects using list index/slicing
with negative indices also requires a count to be
executed.



3.0.0
=====
November 24, 2015
Expand Down
13 changes: 10 additions & 3 deletions cassandra/cqlengine/query.py
Original file line number Diff line number Diff line change
Expand Up @@ -700,7 +700,9 @@ class Comment(Model):

def count(self):
"""
Returns the number of rows matched by this query
Returns the number of rows matched by this query.

*Note: This function executes a SELECT COUNT() and has a performance cost on large datasets*
"""
if self._batch:
raise CQLEngineException("Only inserts, updates, and deletes are available in batch mode")
Expand Down Expand Up @@ -751,14 +753,19 @@ class Automobile(Model):

def limit(self, v):
"""
Limits the number of results returned by Cassandra.
Limits the number of results returned by Cassandra. Use *0* or *None* to disable.

*Note that CQL's default limit is 10,000, so all queries without a limit set explicitly will have an implicit limit of 10,000*

.. code-block:: python

# Fetch 100 users
for user in User.objects().limit(100):
print(user)

# Fetch all users
for user in User.objects().limit(None):
print(user)
"""

if v is None:
Expand All @@ -780,7 +787,7 @@ def fetch_size(self, v):
"""
Sets the number of rows that are fetched at a time.

*Note that driver's default fetch size is 5000.
*Note that driver's default fetch size is 5000.*

.. code-block:: python

Expand Down
8 changes: 8 additions & 0 deletions docs/api/cassandra/cqlengine/query.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ The methods here are used to filter, order, and constrain results.

.. automethod:: count

.. method:: len(queryset)

Returns the number of rows matched by this query. This function uses :meth:`~.cassandra.cqlengine.query.ModelQuerySet.count` internally.

*Note: This function executes a SELECT COUNT() and has a performance cost on large datasets*

.. automethod:: distinct

.. automethod:: filter
Expand All @@ -26,6 +32,8 @@ The methods here are used to filter, order, and constrain results.

.. automethod:: limit

.. automethod:: fetch_size

.. automethod:: if_not_exists

.. automethod:: if_exists
Expand Down
9 changes: 8 additions & 1 deletion docs/cqlengine/queryset.rst
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ Accessing objects in a QuerySet
q[0] #returns the first result
q[1] #returns the second result

.. note::

* CQL does not support specifying a start position in it's queries. Therefore, accessing elements using array indexing will load every result up to the index value requested
* Using negative indices requires a "SELECT COUNT()" to be executed. This has a performance cost on large datasets.

* list slicing
.. code-block:: python
Expand All @@ -87,7 +91,10 @@ Accessing objects in a QuerySet
q[1:] #returns all results except the first
q[1:9] #returns a slice of the results

*Note: CQL does not support specifying a start position in it's queries. Therefore, accessing elements using array indexing / slicing will load every result up to the index value requested*
.. note::

* CQL does not support specifying a start position in it's queries. Therefore, accessing elements using array slicing will load every result up to the index value requested
* Using negative indices requires a "SELECT COUNT()" to be executed. This has a performance cost on large datasets.

* calling :attr:`get() <query.QuerySet.get>` on the queryset
.. code-block:: python
Expand Down