Esempio n. 1
0
 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)
Esempio n. 2
0
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
Esempio n. 3
0
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
Esempio n. 5
0
    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()
Esempio n. 9
0
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)
Esempio n. 10
0
 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)
Esempio n. 12
0
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)
Esempio n. 14
0
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)
Esempio n. 15
0
 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)