doc: add discussion about LWT results
This commit is contained in:
@@ -305,6 +305,9 @@ class Statement(object):
|
|||||||
Serial consistency levels may only be used against Cassandra 2.0+
|
Serial consistency levels may only be used against Cassandra 2.0+
|
||||||
and the :attr:`~.Cluster.protocol_version` must be set to 2 or higher.
|
and the :attr:`~.Cluster.protocol_version` must be set to 2 or higher.
|
||||||
|
|
||||||
|
See :doc:`/lwt` for a discussion on how to work with results returned from
|
||||||
|
conditional statements.
|
||||||
|
|
||||||
.. versionadded:: 2.0.0
|
.. versionadded:: 2.0.0
|
||||||
""")
|
""")
|
||||||
|
|
||||||
|
|||||||
@@ -33,6 +33,9 @@ Contents
|
|||||||
:doc:`query_paging`
|
:doc:`query_paging`
|
||||||
Notes on paging large query results.
|
Notes on paging large query results.
|
||||||
|
|
||||||
|
:doc:`lwt`
|
||||||
|
Working with results of conditional requests
|
||||||
|
|
||||||
:doc:`user_defined_types`
|
:doc:`user_defined_types`
|
||||||
Working with Cassandra 2.1's user-defined types.
|
Working with Cassandra 2.1's user-defined types.
|
||||||
|
|
||||||
@@ -51,6 +54,7 @@ Contents
|
|||||||
upgrading
|
upgrading
|
||||||
performance
|
performance
|
||||||
query_paging
|
query_paging
|
||||||
|
lwt
|
||||||
security
|
security
|
||||||
user_defined_types
|
user_defined_types
|
||||||
object_mapper
|
object_mapper
|
||||||
|
|||||||
91
docs/lwt.rst
Normal file
91
docs/lwt.rst
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
Lightweight Transactions (Compare-and-set)
|
||||||
|
==========================================
|
||||||
|
|
||||||
|
Lightweight Transactions (LWTs) are mostly pass-through CQL for the driver. However,
|
||||||
|
the server returns some specialized results indicating the outcome and optional state
|
||||||
|
preceding the transaction.
|
||||||
|
|
||||||
|
For pertinent execution parameters, see :attr:`.Statement.serial_consistency_level`.
|
||||||
|
|
||||||
|
This section discusses working with specialized result sets returned by the server for LWTs,
|
||||||
|
and how to work with them using the driver.
|
||||||
|
|
||||||
|
|
||||||
|
Specialized Results
|
||||||
|
-------------------
|
||||||
|
The result returned from a LWT request is always a single row result. It will always have
|
||||||
|
prepended a special column named ``[applied]``. How this value appears in your results depends
|
||||||
|
on the row factory in use. See below for examples.
|
||||||
|
|
||||||
|
The value of this ``[applied]`` column is boolean value indicating whether or not the transaction was applied.
|
||||||
|
If ``True``, it is the only column in the result. If ``False``, the additional columns depend on the LWT operation being
|
||||||
|
executed:
|
||||||
|
|
||||||
|
- When using a ``UPDATE ... IF "col" = ...`` clause, the result will contain the ``[applied]`` column, plus the existing columns
|
||||||
|
and values for any columns in the ``IF`` clause (and thus the value that caused the transaction to fail).
|
||||||
|
|
||||||
|
- When using ``INSERT ... IF NOT EXISTS``, the result will contain the ``[applied]`` column, plus all columns and values
|
||||||
|
of the existing row that rejected the transaction.
|
||||||
|
|
||||||
|
- ``UPDATE .. IF EXISTS`` never has additional columns, regardless of ``[applied]`` status.
|
||||||
|
|
||||||
|
How the ``[applied]]`` column manifests depends on the row factory in use. Considering the following (initially empty) table::
|
||||||
|
|
||||||
|
CREATE TABLE test.t (
|
||||||
|
k int PRIMARY KEY,
|
||||||
|
v int,
|
||||||
|
x int
|
||||||
|
)
|
||||||
|
|
||||||
|
... the following sections show the expected result for a number of example statements, using the three base row factories.
|
||||||
|
|
||||||
|
named_tuple_factory (default)
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
The name ``[applied]`` is not a valid Python identifier, so the square brackets are actually removed
|
||||||
|
from the attribute for the resulting ``namedtuple``. The row always has a boolean column ``applied`` in position 0::
|
||||||
|
|
||||||
|
>>> session.execute("INSERT INTO t (k,v) VALUES (0,0) IF NOT EXISTS")
|
||||||
|
Row(applied=True)
|
||||||
|
|
||||||
|
>>> session.execute("INSERT INTO t (k,v) VALUES (0,0) IF NOT EXISTS")
|
||||||
|
Row(applied=False, k=0, v=0, x=None)
|
||||||
|
|
||||||
|
>>> session.execute("UPDATE t SET v = 1, x = 2 WHERE k = 0 IF v =0")
|
||||||
|
Row(applied=True)
|
||||||
|
|
||||||
|
>>> session.execute("UPDATE t SET v = 1, x = 2 WHERE k = 0 IF v =0 AND x = 1")
|
||||||
|
Row(applied=False, v=1, x=2)
|
||||||
|
|
||||||
|
tuple_factory
|
||||||
|
~~~~~~~~~~~~~
|
||||||
|
This return type does not refer to names, but the boolean value ``applied`` is always present in position 0::
|
||||||
|
|
||||||
|
>>> session.execute("INSERT INTO t (k,v) VALUES (0,0) IF NOT EXISTS")
|
||||||
|
(True,)
|
||||||
|
|
||||||
|
>>> session.execute("INSERT INTO t (k,v) VALUES (0,0) IF NOT EXISTS")
|
||||||
|
(False, 0, 0, None)
|
||||||
|
|
||||||
|
>>> session.execute("UPDATE t SET v = 1, x = 2 WHERE k = 0 IF v =0")
|
||||||
|
(True,)
|
||||||
|
|
||||||
|
>>> session.execute("UPDATE t SET v = 1, x = 2 WHERE k = 0 IF v =0 AND x = 1")
|
||||||
|
(False, 1, 2)
|
||||||
|
|
||||||
|
dict_factory
|
||||||
|
~~~~~~~~~~~~
|
||||||
|
The retuned ``dict`` contains the ``[applied]`` key::
|
||||||
|
|
||||||
|
>>> session.execute("INSERT INTO t (k,v) VALUES (0,0) IF NOT EXISTS")
|
||||||
|
{u'[applied]': True}
|
||||||
|
|
||||||
|
>>> session.execute("INSERT INTO t (k,v) VALUES (0,0) IF NOT EXISTS")
|
||||||
|
{u'x': 2, u'[applied]': False, u'v': 1}
|
||||||
|
|
||||||
|
>>> session.execute("UPDATE t SET v = 1, x = 2 WHERE k = 0 IF v =0")
|
||||||
|
{u'x': None, u'[applied]': False, u'k': 0, u'v': 0}
|
||||||
|
|
||||||
|
>>> session.execute("UPDATE t SET v = 1, x = 2 WHERE k = 0 IF v =0 AND x = 1")
|
||||||
|
{u'[applied]': True}
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user