def test_get_cluster_fails_without_existing_connection(self): """ Users can't get the default cluster without having a default connection set. """ with self.assertRaisesRegexp(connection.CQLEngineException, self.no_registered_connection_msg): connection.get_cluster(connection=None)
def _get_table_metadata(model, connection=None): # returns the table as provided by the native driver for a given model cluster = get_cluster(connection) ks = model._get_keyspace() table = model._raw_column_family_name() table = cluster.metadata.keyspaces[ks].tables[table] return table
def initialise(): """Initialise the Cassandra connection repl_factor, dc_replication_map, keyspace variables are used to configure the connection. See the cfg object in the :mod:`radon.model.config` module, . :return: A boolean which indicates if the connection is successful :rtype: bool """ if not connect(): return False repl_factor = cfg.dse_repl_factor dc_replication_map = cfg.dse_dc_replication_map keyspace = cfg.dse_keyspace cluster = connection.get_cluster() if keyspace in cluster.metadata.keyspaces: # If the keyspace already exists we do not create it. Should we raise # an error return True if cfg.dse_strategy == "NetworkTopologyStrategy": create_keyspace_network_topology(keyspace, dc_replication_map, True) else: create_keyspace_simple(keyspace, repl_factor, True) return True
def test_destroy(): cfg.dse_keyspace = TEST_KEYSPACE initialise() create_keyspace_simple(TEST_KEYSPACE, 1, True) cluster = connection.get_cluster() assert TEST_KEYSPACE in cluster.metadata.keyspaces destroy() assert TEST_KEYSPACE not in cluster.metadata.keyspaces
def __create_keyspace(name, durable_writes, strategy_class, strategy_options, connection=None): cluster = get_cluster(connection) if name not in cluster.metadata.keyspaces: log.info(format_log_context("Creating keyspace %s", connection=connection), name) ks_meta = metadata.KeyspaceMetadata(name, durable_writes, strategy_class, strategy_options) execute(ks_meta.as_cql_query(), connection=connection) else: log.info(format_log_context("Not creating keyspace %s because it already exists", connection=connection), name)
def test_initialise(): cfg.dse_keyspace = TEST_KEYSPACE assert initialise() == True cluster = connection.get_cluster() # Check keyspace has been created assert cfg.dse_keyspace in cluster.metadata.keyspaces # Keyspace should already exist assert initialise() == True destroy()
def test_keyspace_simple(): cfg.dse_keyspace = TEST_KEYSPACE cfg.dse_strategy = "SimpleStrategy" assert initialise() == True cluster = connection.get_cluster() # Check keyspace has been created assert TEST_KEYSPACE in cluster.metadata.keyspaces destroy() # Check keyspace has been deleted assert TEST_KEYSPACE not in cluster.metadata.keyspaces
def test_tables(): cfg.dse_keyspace = TEST_KEYSPACE # list of tables that has to be created ls_tables = {'data_object', 'group', 'notification', 'tree_node', 'user'} initialise() create_tables() cluster = connection.get_cluster() created_tables = set( cluster.metadata.keyspaces[TEST_KEYSPACE].tables.keys()) assert created_tables.difference(ls_tables) == set() destroy()
def _sync_type(ks_name, type_model, omit_subtypes=None, connection=None): syncd_sub_types = omit_subtypes or set() for field in type_model._fields.values(): udts = [] columns.resolve_udts(field, udts) for udt in [u for u in udts if u not in syncd_sub_types]: _sync_type(ks_name, udt, syncd_sub_types, connection=connection) syncd_sub_types.add(udt) type_name = type_model.type_name() type_name_qualified = "%s.%s" % (ks_name, type_name) cluster = get_cluster(connection) keyspace = cluster.metadata.keyspaces[ks_name] defined_types = keyspace.user_types if type_name not in defined_types: log.debug(format_log_context("sync_type creating new type %s", keyspace=ks_name, connection=connection), type_name_qualified) cql = get_create_type(type_model, ks_name) execute(cql, connection=connection) cluster.refresh_user_type_metadata(ks_name, type_name) type_model.register_for_keyspace(ks_name, connection=connection) else: type_meta = defined_types[type_name] defined_fields = type_meta.field_names model_fields = set() for field in type_model._fields.values(): model_fields.add(field.db_field_name) if field.db_field_name not in defined_fields: execute("ALTER TYPE {0} ADD {1}".format(type_name_qualified, field.get_column_def()), connection=connection) else: field_type = type_meta.field_types[defined_fields.index(field.db_field_name)] if field_type != field.db_type: msg = format_log_context('Existing user type {0} has field "{1}" with a type ({2}) differing from the model user type ({3}).' ' UserType should be updated.', keyspace=ks_name, connection=connection) msg = msg.format(type_name_qualified, field.db_field_name, field_type, field.db_type) warnings.warn(msg) log.warning(msg) type_model.register_for_keyspace(ks_name, connection=connection) if len(defined_fields) == len(model_fields): log.info(format_log_context("Type %s did not require synchronization", keyspace=ks_name, connection=connection), type_name_qualified) return db_fields_not_in_model = model_fields.symmetric_difference(defined_fields) if db_fields_not_in_model: msg = format_log_context("Type %s has fields not referenced by model: %s", keyspace=ks_name, connection=connection) log.info(msg, type_name_qualified, db_fields_not_in_model)
def _get_partition_keys(self): try: table_meta = get_cluster( self._get_connection()).metadata.keyspaces[ self.keyspace].tables[self.name] self.__partition_keys = OrderedDict( (pk.name, Column(primary_key=True, partition_key=True, db_field=pk.name) ) for pk in table_meta.partition_key) except Exception as e: raise CQLEngineException( "Failed inspecting partition keys for {0}." "Ensure cqlengine is connected before attempting this with NamedTable." .format(self.column_family_name()))
def test_db_field_override(self): """ Tests for db_field override Tests to ensure that udt's in models can specify db_field for a particular field and that it will be honored. @since 3.1.0 @jira_ticket PYTHON-346 @expected_result The actual cassandra column will use the db_field specified. @test_category data_types:udt """ class db_field_different(UserType): age = columns.Integer(db_field='a') name = columns.Text(db_field='n') class TheModel(Model): id = columns.Integer(primary_key=True) info = columns.UserDefinedType(db_field_different) sync_table(TheModel) self.addCleanup(drop_table, TheModel) cluster = connection.get_cluster() type_meta = cluster.metadata.keyspaces[TheModel._get_keyspace()].user_types[db_field_different.type_name()] type_fields = (db_field_different.age.column, db_field_different.name.column) self.assertEqual(len(type_meta.field_names), len(type_fields)) for f in type_fields: self.assertIn(f.db_field_name, type_meta.field_names) id = 0 age = 42 name = 'John' info = db_field_different(age=age, name=name) TheModel.create(id=id, info=info) self.assertEqual(1, TheModel.objects.count()) john = TheModel.objects.first() self.assertEqual(john.id, id) info = john.info self.assertIsInstance(info, db_field_different) self.assertEqual(info.age, age) self.assertEqual(info.name, name) # also excercise the db_Field mapping self.assertEqual(info.a, age) self.assertEqual(info.n, name)
def _drop_table(model, connection=None): if not _allow_schema_modification(): return connection = connection or model._get_connection() # don't try to delete non existant tables meta = get_cluster(connection).metadata ks_name = model._get_keyspace() raw_cf_name = model._raw_column_family_name() try: meta.keyspaces[ks_name].tables[raw_cf_name] execute('DROP TABLE {0};'.format(model.column_family_name()), connection=connection) except KeyError: pass
def test_create_drop_succeeeds(self): cluster = get_cluster() keyspace_ss = 'test_ks_ss' self.assertNotIn(keyspace_ss, cluster.metadata.keyspaces) management.create_keyspace_simple(keyspace_ss, 2) self.assertIn(keyspace_ss, cluster.metadata.keyspaces) management.drop_keyspace(keyspace_ss) self.assertNotIn(keyspace_ss, cluster.metadata.keyspaces) keyspace_nts = 'test_ks_nts' self.assertNotIn(keyspace_nts, cluster.metadata.keyspaces) management.create_keyspace_network_topology(keyspace_nts, {'dc1': 1}) self.assertIn(keyspace_nts, cluster.metadata.keyspaces) management.drop_keyspace(keyspace_nts) self.assertNotIn(keyspace_nts, cluster.metadata.keyspaces)
def _sync_table(model, connection=None): if not _allow_schema_modification(): return if not issubclass(model, Model): raise CQLEngineException("Models must be derived from base Model.") if model.__abstract__: raise CQLEngineException("cannot create table from abstract model") cf_name = model.column_family_name() raw_cf_name = model._raw_column_family_name() ks_name = model._get_keyspace() connection = connection or model._get_connection() cluster = get_cluster(connection) try: keyspace = cluster.metadata.keyspaces[ks_name] except KeyError: msg = format_log_context("Keyspace '{0}' for model {1} does not exist.", connection=connection) raise CQLEngineException(msg.format(ks_name, model)) tables = keyspace.tables syncd_types = set() for col in model._columns.values(): udts = [] columns.resolve_udts(col, udts) for udt in [u for u in udts if u not in syncd_types]: _sync_type(ks_name, udt, syncd_types, connection=connection) if raw_cf_name not in tables: log.debug(format_log_context("sync_table creating new table %s", keyspace=ks_name, connection=connection), cf_name) qs = _get_create_table(model) try: execute(qs, connection=connection) except CQLEngineException as ex: # 1.2 doesn't return cf names, so we have to examine the exception # and ignore if it says the column family already exists if "Cannot add already existing column family" not in unicode(ex): raise else: log.debug(format_log_context("sync_table checking existing table %s", keyspace=ks_name, connection=connection), cf_name) table_meta = tables[raw_cf_name] _validate_pk(model, table_meta) table_columns = table_meta.columns model_fields = set() for model_name, col in model._columns.items(): db_name = col.db_field_name model_fields.add(db_name) if db_name in table_columns: col_meta = table_columns[db_name] if col_meta.cql_type != col.db_type: msg = format_log_context('Existing table {0} has column "{1}" with a type ({2}) differing from the model type ({3}).' ' Model should be updated.', keyspace=ks_name, connection=connection) msg = msg.format(cf_name, db_name, col_meta.cql_type, col.db_type) warnings.warn(msg) log.warning(msg) continue if col.primary_key or col.primary_key: msg = format_log_context("Cannot add primary key '{0}' (with db_field '{1}') to existing table {2}", keyspace=ks_name, connection=connection) raise CQLEngineException(msg.format(model_name, db_name, cf_name)) query = "ALTER TABLE {0} add {1}".format(cf_name, col.get_column_def()) execute(query, connection=connection) db_fields_not_in_model = model_fields.symmetric_difference(table_columns) if db_fields_not_in_model: msg = format_log_context("Table {0} has fields not referenced by model: {1}", keyspace=ks_name, connection=connection) log.info(msg.format(cf_name, db_fields_not_in_model)) _update_options(model, connection=connection) table = cluster.metadata.keyspaces[ks_name].tables[raw_cf_name] indexes = [c for n, c in model._columns.items() if c.index] # TODO: support multiple indexes in C* 3.0+ for column in indexes: index_name = _get_index_name_by_column(table, column.db_field_name) if index_name: continue qs = ['CREATE INDEX'] qs += ['ON {0}'.format(cf_name)] qs += ['("{0}")'.format(column.db_field_name)] qs = ' '.join(qs) execute(qs, connection=connection)
def _drop_keyspace(name, connection=None): cluster = get_cluster(connection) if name in cluster.metadata.keyspaces: execute("DROP KEYSPACE {0}".format(metadata.protect_name(name)), connection=connection)