109 lines
4.4 KiB
ReStructuredText
109 lines
4.4 KiB
ReStructuredText
=============
|
|
Batch Queries
|
|
=============
|
|
|
|
cqlengine supports batch queries using the BatchQuery class. Batch queries can be started and stopped manually, or within a context manager. To add queries to the batch object, you just need to precede the create/save/delete call with a call to batch, and pass in the batch object.
|
|
|
|
|
|
Batch Query General Use Pattern
|
|
===============================
|
|
|
|
You can only create, update, and delete rows with a batch query, attempting to read rows out of the database with a batch query will fail.
|
|
|
|
.. code-block:: python
|
|
|
|
from cassandra.cqlengine import BatchQuery
|
|
|
|
#using a context manager
|
|
with BatchQuery() as b:
|
|
now = datetime.now()
|
|
em1 = ExampleModel.batch(b).create(example_type=0, description="1", created_at=now)
|
|
em2 = ExampleModel.batch(b).create(example_type=0, description="2", created_at=now)
|
|
em3 = ExampleModel.batch(b).create(example_type=0, description="3", created_at=now)
|
|
|
|
# -- or --
|
|
|
|
#manually
|
|
b = BatchQuery()
|
|
now = datetime.now()
|
|
em1 = ExampleModel.batch(b).create(example_type=0, description="1", created_at=now)
|
|
em2 = ExampleModel.batch(b).create(example_type=0, description="2", created_at=now)
|
|
em3 = ExampleModel.batch(b).create(example_type=0, description="3", created_at=now)
|
|
b.execute()
|
|
|
|
# updating in a batch
|
|
|
|
b = BatchQuery()
|
|
em1.description = "new description"
|
|
em1.batch(b).save()
|
|
em2.description = "another new description"
|
|
em2.batch(b).save()
|
|
b.execute()
|
|
|
|
# deleting in a batch
|
|
b = BatchQuery()
|
|
ExampleModel.objects(id=some_id).batch(b).delete()
|
|
ExampleModel.objects(id=some_id2).batch(b).delete()
|
|
b.execute()
|
|
|
|
|
|
Typically you will not want the block to execute if an exception occurs inside the `with` block. However, in the case that this is desirable, it's achievable by using the following syntax:
|
|
|
|
.. code-block:: python
|
|
|
|
with BatchQuery(execute_on_exception=True) as b:
|
|
LogEntry.batch(b).create(k=1, v=1)
|
|
mystery_function() # exception thrown in here
|
|
LogEntry.batch(b).create(k=1, v=2) # this code is never reached due to the exception, but anything leading up to here will execute in the batch.
|
|
|
|
If an exception is thrown somewhere in the block, any statements that have been added to the batch will still be executed. This is useful for some logging situations.
|
|
|
|
Batch Query Execution Callbacks
|
|
===============================
|
|
|
|
In order to allow secondary tasks to be chained to the end of batch, BatchQuery instances allow callbacks to be
|
|
registered with the batch, to be executed immediately after the batch executes.
|
|
|
|
Multiple callbacks can be attached to same BatchQuery instance, they are executed in the same order that they
|
|
are added to the batch.
|
|
|
|
The callbacks attached to a given batch instance are executed only if the batch executes. If the batch is used as a
|
|
context manager and an exception is raised, the queued up callbacks will not be run.
|
|
|
|
.. code-block:: python
|
|
|
|
def my_callback(*args, **kwargs):
|
|
pass
|
|
|
|
batch = BatchQuery()
|
|
|
|
batch.add_callback(my_callback)
|
|
batch.add_callback(my_callback, 'positional arg', named_arg='named arg value')
|
|
|
|
# if you need reference to the batch within the callback,
|
|
# just trap it in the arguments to be passed to the callback:
|
|
batch.add_callback(my_callback, cqlengine_batch=batch)
|
|
|
|
# once the batch executes...
|
|
batch.execute()
|
|
|
|
# the effect of the above scheduled callbacks will be similar to
|
|
my_callback()
|
|
my_callback('positional arg', named_arg='named arg value')
|
|
my_callback(cqlengine_batch=batch)
|
|
|
|
Failure in any of the callbacks does not affect the batch's execution, as the callbacks are started after the execution
|
|
of the batch is complete.
|
|
|
|
Logged vs Unlogged Batches
|
|
---------------------------
|
|
By default, queries in cqlengine are LOGGED, which carries additional overhead from UNLOGGED. To explicitly state which batch type to use, simply:
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
from cassandra.cqlengine.query import BatchType
|
|
with BatchQuery(batch_type=BatchType.Unlogged) as b:
|
|
LogEntry.batch(b).create(k=1, v=1)
|
|
LogEntry.batch(b).create(k=1, v=2)
|