Skip to content

Commit e300724

Browse files
Merge pull request datastax#1046 from datastax/python-1009-take2
[PYTHON-1009] Support execution profiles in cqlengine
2 parents 30a0e27 + f845a5b commit e300724

File tree

4 files changed

+104
-17
lines changed

4 files changed

+104
-17
lines changed

CHANGELOG.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
3.20.0
2+
======
3+
Unreleased
4+
5+
Bug Fixes
6+
---------
7+
* Connection setup methods prevent using ExecutionProfile in cqlengine (PYTHON-1009)
8+
19
3.19.0
210
======
311
August 26, 2019

cassandra/cqlengine/connection.py

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
import six
1818
import threading
1919

20-
from cassandra.cluster import Cluster, _NOT_SET, NoHostAvailable, UserTypeDoesNotExist, ConsistencyLevel
20+
from cassandra.cluster import Cluster, _ConfigMode, _NOT_SET, NoHostAvailable, UserTypeDoesNotExist, ConsistencyLevel
2121
from cassandra.query import SimpleStatement, dict_factory
2222

2323
from cassandra.cqlengine import CQLEngineException
@@ -108,17 +108,21 @@ def setup(self):
108108
self.lazy_connect = True
109109
raise
110110

111-
if self.consistency is not None:
112-
self.session.default_consistency_level = self.consistency
113-
114111
if DEFAULT_CONNECTION in _connections and _connections[DEFAULT_CONNECTION] == self:
115112
cluster = _connections[DEFAULT_CONNECTION].cluster
116113
session = _connections[DEFAULT_CONNECTION].session
117114

118115
self.setup_session()
119116

120117
def setup_session(self):
121-
self.session.row_factory = dict_factory
118+
if self.cluster._config_mode == _ConfigMode.PROFILES:
119+
self.cluster.profile_manager.default.row_factory = dict_factory
120+
if self.consistency is not None:
121+
self.cluster.profile_manager.default.consistency_level = self.consistency
122+
else:
123+
self.session.row_factory = dict_factory
124+
if self.consistency is not None:
125+
self.session.default_consistency_level = self.consistency
122126
enc = self.session.encoder
123127
enc.mapping[tuple] = enc.cql_encode_tuple
124128
_register_known_types(self.session.cluster)
@@ -182,10 +186,7 @@ def register_connection(name, hosts=None, consistency=None, lazy_connect=False,
182186
"Session configuration arguments and 'session' argument are mutually exclusive"
183187
)
184188
conn = Connection.from_session(name, session=session)
185-
conn.setup_session()
186189
else: # use hosts argument
187-
if consistency is None:
188-
consistency = ConsistencyLevel.LOCAL_ONE
189190
conn = Connection(
190191
name, hosts=hosts,
191192
consistency=consistency, lazy_connect=lazy_connect,
@@ -281,8 +282,12 @@ def set_session(s):
281282
if conn.session:
282283
log.warning("configuring new default session for cqlengine when one was already set")
283284

284-
if s.row_factory is not dict_factory:
285-
raise CQLEngineException("Failed to initialize: 'Session.row_factory' must be 'dict_factory'.")
285+
if not any([
286+
s.cluster.profile_manager.default.row_factory is dict_factory and s.cluster._config_mode in [_ConfigMode.PROFILES, _ConfigMode.UNCOMMITTED],
287+
s.row_factory is dict_factory and s.cluster._config_mode in [_ConfigMode.LEGACY, _ConfigMode.UNCOMMITTED],
288+
]):
289+
raise CQLEngineException("Failed to initialize: row_factory must be 'dict_factory'")
290+
286291
conn.session = s
287292
conn.cluster = s.cluster
288293

tests/integration/cqlengine/connections/test_connection.py

Lines changed: 75 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,17 @@
1818
import unittest # noqa
1919

2020

21+
from cassandra import ConsistencyLevel
2122
from cassandra.cqlengine.models import Model
22-
from cassandra.cqlengine import columns, connection
23+
from cassandra.cqlengine import columns, connection, models
2324
from cassandra.cqlengine.management import sync_table
24-
from cassandra.cluster import Cluster, _clusters_for_shutdown
25+
from cassandra.cluster import Cluster, ExecutionProfile, _clusters_for_shutdown, _ConfigMode, EXEC_PROFILE_DEFAULT
26+
from cassandra.policies import RoundRobinPolicy
2527
from cassandra.query import dict_factory
2628

27-
from tests.integration import PROTOCOL_VERSION, execute_with_long_wait_retry, local
29+
from tests.integration import CASSANDRA_IP, PROTOCOL_VERSION, execute_with_long_wait_retry, local
2830
from tests.integration.cqlengine.base import BaseCassEngTestCase
2931
from tests.integration.cqlengine import DEFAULT_KEYSPACE, setup_connection
30-
from cassandra.cqlengine import models
31-
32-
from mock import patch
3332

3433

3534
class TestConnectModel(Model):
@@ -127,3 +126,73 @@ def test_connection_session_switch(self):
127126
connection.set_session(self.session2)
128127
self.assertEqual(1, TestConnectModel.objects.count())
129128
self.assertEqual(TestConnectModel.objects.first(), TCM2)
129+
130+
131+
class ConnectionModel(Model):
132+
key = columns.Integer(primary_key=True)
133+
some_data = columns.Text()
134+
135+
136+
class ConnectionInitTest(unittest.TestCase):
137+
def test_default_connection_uses_legacy(self):
138+
connection.default()
139+
conn = connection.get_connection()
140+
self.assertEqual(conn.cluster._config_mode, _ConfigMode.LEGACY)
141+
142+
def test_connection_with_legacy_settings(self):
143+
connection.setup(
144+
hosts=[CASSANDRA_IP],
145+
default_keyspace=DEFAULT_KEYSPACE,
146+
consistency=ConsistencyLevel.LOCAL_ONE
147+
)
148+
conn = connection.get_connection()
149+
self.assertEqual(conn.cluster._config_mode, _ConfigMode.LEGACY)
150+
151+
def test_connection_from_session_with_execution_profile(self):
152+
cluster = Cluster(execution_profiles={EXEC_PROFILE_DEFAULT: ExecutionProfile(row_factory=dict_factory)})
153+
session = cluster.connect()
154+
connection.default()
155+
connection.set_session(session)
156+
conn = connection.get_connection()
157+
self.assertEqual(conn.cluster._config_mode, _ConfigMode.PROFILES)
158+
159+
def test_connection_from_session_with_legacy_settings(self):
160+
cluster = Cluster(load_balancing_policy=RoundRobinPolicy())
161+
session = cluster.connect()
162+
session.row_factory = dict_factory
163+
connection.set_session(session)
164+
conn = connection.get_connection()
165+
self.assertEqual(conn.cluster._config_mode, _ConfigMode.LEGACY)
166+
167+
def test_uncommitted_session_uses_legacy(self):
168+
cluster = Cluster()
169+
session = cluster.connect()
170+
session.row_factory = dict_factory
171+
connection.set_session(session)
172+
conn = connection.get_connection()
173+
self.assertEqual(conn.cluster._config_mode, _ConfigMode.LEGACY)
174+
175+
def test_legacy_insert_query(self):
176+
connection.setup(
177+
hosts=[CASSANDRA_IP],
178+
default_keyspace=DEFAULT_KEYSPACE,
179+
consistency=ConsistencyLevel.LOCAL_ONE
180+
)
181+
self.assertEqual(connection.get_connection().cluster._config_mode, _ConfigMode.LEGACY)
182+
183+
sync_table(ConnectionModel)
184+
ConnectionModel.objects.create(key=0, some_data='text0')
185+
ConnectionModel.objects.create(key=1, some_data='text1')
186+
self.assertEqual(ConnectionModel.objects(key=0)[0].some_data, 'text0')
187+
188+
def test_execution_profile_insert_query(self):
189+
cluster = Cluster(execution_profiles={EXEC_PROFILE_DEFAULT: ExecutionProfile(row_factory=dict_factory)})
190+
session = cluster.connect()
191+
connection.default()
192+
connection.set_session(session)
193+
self.assertEqual(connection.get_connection().cluster._config_mode, _ConfigMode.PROFILES)
194+
195+
sync_table(ConnectionModel)
196+
ConnectionModel.objects.create(key=0, some_data='text0')
197+
ConnectionModel.objects.create(key=1, some_data='text1')
198+
self.assertEqual(ConnectionModel.objects(key=0)[0].some_data, 'text0')

tests/unit/cqlengine/test_connection.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
except ImportError:
1818
import unittest # noqa
1919

20+
from cassandra.cluster import _ConfigMode
2021
from cassandra.cqlengine import connection
2122
from cassandra.query import dict_factory
2223

@@ -38,9 +39,13 @@ def test_set_session_without_existing_connection(self):
3839
"""
3940
Users can set the default session without having a default connection set.
4041
"""
42+
mock_cluster = Mock(
43+
_config_mode=_ConfigMode.LEGACY,
44+
)
4145
mock_session = Mock(
4246
row_factory=dict_factory,
43-
encoder=Mock(mapping={})
47+
encoder=Mock(mapping={}),
48+
cluster=mock_cluster,
4449
)
4550
connection.set_session(mock_session)
4651

0 commit comments

Comments
 (0)