diff --git a/cqlengine/connection.py b/cqlengine/connection.py index 8e465e8d..33c9bbe0 100644 --- a/cqlengine/connection.py +++ b/cqlengine/connection.py @@ -5,7 +5,7 @@ from collections import namedtuple from cassandra.cluster import Cluster, NoHostAvailable from cassandra.query import SimpleStatement, Statement -from cqlengine.exceptions import TransactionException +from cqlengine.exceptions import LWTException import six try: @@ -112,12 +112,6 @@ def execute(query, params=None, consistency_level=None): params = params or {} result = session.execute(query, params) - if result and result[0].get('[applied]', True) is False: - result[0].pop('[applied]') - expected = ', '.join('{0}={1}'.format(t.field, t.value) for t in statement.transactions) - actual = ', '.join('{0}={1}'.format(f, v) for f, v in result[0].items()) - message = 'Transaction statement failed: Expected: {0} Actual: {1}'.format(expected, actual) - raise TransactionException(message) return result def get_session(): diff --git a/cqlengine/exceptions.py b/cqlengine/exceptions.py index 75473de6..f40f8af7 100644 --- a/cqlengine/exceptions.py +++ b/cqlengine/exceptions.py @@ -2,7 +2,6 @@ class CQLEngineException(Exception): pass class ModelException(CQLEngineException): pass class ValidationError(CQLEngineException): pass -class TransactionException(CQLEngineException): pass class UndefinedKeyspaceException(CQLEngineException): pass class LWTException(CQLEngineException): pass diff --git a/cqlengine/models.py b/cqlengine/models.py index 69b62978..5003b3c0 100644 --- a/cqlengine/models.py +++ b/cqlengine/models.py @@ -266,7 +266,7 @@ class BaseModel(object): objects = QuerySetDescriptor() ttl = TTLDescriptor() consistency = ConsistencyDescriptor() - transaction = TransactionDescriptor() + iff = TransactionDescriptor() # custom timestamps, see USING TIMESTAMP X timestamp = TimestampDescriptor() diff --git a/cqlengine/query.py b/cqlengine/query.py index cc00d5f1..d9bef1aa 100644 --- a/cqlengine/query.py +++ b/cqlengine/query.py @@ -5,7 +5,7 @@ from cqlengine import BaseContainerColumn, Map, columns from cqlengine.columns import Counter, List, Set from cqlengine.connection import execute -from cqlengine.exceptions import CQLEngineException, ValidationError, TransactionException, LWTException +from cqlengine.exceptions import CQLEngineException, ValidationError, LWTException from cqlengine.functions import Token, BaseQueryFunction, QueryValue, UnicodeMixin #CQL 3 reference: @@ -849,14 +849,8 @@ class DMLQuery(object): return self._batch.add_query(q) else: tmp = execute(q, consistency_level=self._consistency) - if self._if_not_exists: + if self._if_not_exists or self._transaction: check_applied(tmp) - if self._transaction and tmp[0].get('[applied]', True) is False: - tmp[0].pop('[applied]') - expected = ', '.join('{0}={1}'.format(t.field, t.value) for t in q.transactions) - actual = ', '.join('{0}={1}'.format(f, v) for f, v in tmp[0].items()) - message = 'Transaction statement failed: Expected: {0} Actual: {1}'.format(expected, actual) - raise TransactionException(message) return tmp def batch(self, batch_obj): @@ -966,7 +960,7 @@ class DMLQuery(object): if self.instance._has_counter or self.instance._can_update(): return self.update() else: - insert = InsertStatement(self.column_family_name, ttl=self._ttl, timestamp=self._timestamp, if_not_exists=self._if_not_exists, transactions=self._transaction) + insert = InsertStatement(self.column_family_name, ttl=self._ttl, timestamp=self._timestamp, if_not_exists=self._if_not_exists) for name, col in self.instance._columns.items(): val = getattr(self.instance, name, None) if col._val_is_null(val): diff --git a/cqlengine/tests/base.py b/cqlengine/tests/base.py index dea0cc19..96dda91e 100644 --- a/cqlengine/tests/base.py +++ b/cqlengine/tests/base.py @@ -3,8 +3,11 @@ import os import sys import six from cqlengine.connection import get_session +from cqlengine import connection -CASSANDRA_VERSION = int(os.environ['CASSANDRA_VERSION']) +CASSANDRA_VERSION = 20 #int(os.environ['CASSANDRA_VERSION']) + +connection.setup(['192.168.56.103'], 'cqlengine_test') class BaseCassEngTestCase(TestCase): diff --git a/cqlengine/tests/test_transaction.py b/cqlengine/tests/test_transaction.py index 13a4a59d..69e6cb60 100644 --- a/cqlengine/tests/test_transaction.py +++ b/cqlengine/tests/test_transaction.py @@ -2,7 +2,7 @@ __author__ = 'Tim Martin' from cqlengine.management import sync_table, drop_table from cqlengine.tests.base import BaseCassEngTestCase from cqlengine.models import Model -from cqlengine.exceptions import TransactionException +from cqlengine.exceptions import LWTException from uuid import uuid4 from cqlengine import columns import mock @@ -41,7 +41,7 @@ class TestTransaction(BaseCassEngTestCase): t = TestTransactionModel.create(text='blah blah') t.text = 'new blah' t = t.iff(text='something wrong') - self.assertRaises(TransactionException, t.save) + self.assertRaises(LWTException, t.save) def test_blind_update(self): t = TestTransactionModel.create(text='blah blah') @@ -59,4 +59,4 @@ class TestTransaction(BaseCassEngTestCase): t.text = 'something else' uid = t.id qs = TestTransactionModel.objects(id=uid).iff(text='Not dis!') - self.assertRaises(TransactionException, qs.update, text='this will never work') \ No newline at end of file + self.assertRaises(LWTException, qs.update, text='this will never work') \ No newline at end of file diff --git a/docs/topics/models.rst b/docs/topics/models.rst index 618838ec..567e8237 100644 --- a/docs/topics/models.rst +++ b/docs/topics/models.rst @@ -207,6 +207,14 @@ Model Methods This method is supported on Cassandra 2.0 or later. + .. method:: iff(**values) + + Checks to ensure that the values specified are correct on the Cassandra cluster. + Simply specify the column(s) and the expected value(s). As with if_not_exists, + this incurs a performance cost. + + If the insertion isn't applied, a LWTException is raised + .. method:: update(**values) Performs an update on the model instance. You can pass in values to set on the model