Ejemplo n.º 1
0
 def _order_in_memory(self, lhs, rhs):
     for order in self.compiler._get_ordering():
         if LOOKUP_SEP in order:
             raise DatabaseError("JOINs in ordering not supported (%s)" %
                                 order)
         if order == '?':
             result = random.choice([1, 0, -1])
         else:
             column = order.lstrip('-')
             result = cmp(lhs.get(column), rhs.get(column))
             if order.startswith('-'):
                 result *= -1
         if result != 0:
             return result
     return 0
Ejemplo n.º 2
0
 def validate_thread_sharing(self):
     """
     Validate that the connection isn't accessed by another thread than the
     one which originally created it, unless the connection was explicitly
     authorized to be shared between threads (via the `inc_thread_sharing()`
     method). Raise an exception if the validation fails.
     """
     if not (self.allow_thread_sharing or self._thread_ident == _thread.get_ident()):
         raise DatabaseError(
             "DatabaseWrapper objects created in a "
             "thread can only be used in that same thread. The object "
             "with alias '%s' was created in thread id %s and this is "
             "thread id %s."
             % (self.alias, self._thread_ident, _thread.get_ident())
         )
Ejemplo n.º 3
0
    def _value_for_db_key(self, value, field_kind):
        """
        Converts value to be used as a key to an acceptable type.
        On default we do no encoding, only allowing key values directly
        acceptable by the database for its key type (if any).

        The conversion has to be reversible given the field type,
        encoding should preserve comparisons.

        Use this to expand the set of fields that can be used as
        primary keys, return value suitable for a key rather than
        a key itself.
        """
        raise DatabaseError("%s may not be used as primary key field." %
                            field_kind)
Ejemplo n.º 4
0
    def check_query(self):
        """
        Checks if the current query is supported by the database.

        In general, we expect queries requiring JOINs (many-to-many
        relations, abstract model bases, or model spanning filtering),
        using DISTINCT (through `QuerySet.distinct()`, which is not
        required in most situations) or using the SQL-specific
        `QuerySet.extra()` to not work with nonrel back-ends.
        """
        if (len([
                a for a in self.query.alias_map if self.query.alias_refcount[a]
        ]) > 1 or self.query.distinct or self.query.extra
                or self.query.having):
            raise DatabaseError("This query is not supported by the database.")
Ejemplo n.º 5
0
    def _value_for_db(self, value, field, field_kind, db_type, lookup):
        """
        Allows parent to handle nonrel fields, convert AutoField
        keys to ObjectIds and date and times to datetimes.

        Let everything else pass to PyMongo -- when the value is used
        the driver will raise an exception if it got anything
        unacceptable.
        """
        if value is None:
            return None

        # Parent can handle iterable fields and Django wrappers.
        value = super(DatabaseOperations, self)._value_for_db(
            value, field, field_kind, db_type, lookup)

        # Convert decimals to strings preserving order.
        if field_kind == 'DecimalField':
            value = decimal_to_string(
                value, field.max_digits, field.decimal_places)

        # Anything with the "key" db_type is converted to an ObjectId.
        if db_type == 'key':
            try:
                return ObjectId(value)

            # Provide a better message for invalid IDs.
            except (TypeError, InvalidId):
                if isinstance(value, (str, unicode)) and len(value) > 13:
                    value = value[:10] + '...'
                msg = "AutoField (default primary key) values must be " \
                      "strings representing an ObjectId on MongoDB (got " \
                      "%r instead)." % value
                if field.model._meta.db_table == 'django_site':
                    # Also provide some useful tips for (very common) issues
                    # with settings.SITE_ID.
                    msg += " Please make sure your SITE_ID contains a " \
                           "valid ObjectId string."
                raise DatabaseError(msg)

        # PyMongo can only process datatimes?
        elif db_type == 'date':
            return datetime.datetime(value.year, value.month, value.day)
        elif db_type == 'time':
            return datetime.datetime(1, 1, 1, value.hour, value.minute,
                                     value.second, value.microsecond)

        return value
Ejemplo n.º 6
0
    def execute_sql(self, result_type):
        data = {}

        for field, model, value in self.query.values:
            assert field is not None

            if value is None and not field.null:
                raise DatabaseError("It is not possible to set None to a ",
                                    "non-nullable field %s!" % field.name)

            db_type = field.db_type(connection=self.connection)
            value = self.convert_value_for_db(db_type, value)

            data[field.column] = value

        return self.update(data)
Ejemplo n.º 7
0
    def validate_thread_sharing(self):
        """
        检测数据库并没有被其他的线程连接, 除非已经设置为所有线程可以共享

        Validates that the connection isn't accessed by another thread than the
        one which originally created it, unless the connection was explicitly
        authorized to be shared between threads (via the `allow_thread_sharing`
        property). Raises an exception if the validation fails.
        """
        if (not self.allow_thread_sharing
            and self._thread_ident != thread.get_ident()):
                raise DatabaseError("DatabaseWrapper objects created in a "
                    "thread can only be used in that same thread. The object "
                    "with alias '%s' was created in thread id %s and this is "
                    "thread id %s."
                    % (self.alias, self._thread_ident, thread.get_ident()))
Ejemplo n.º 8
0
    def test_create_export_task_record(self, mock_export_task):
        from ..export_tasks import TaskStates

        task_name = "TaskName"
        export_provider_task_name = "ExportProviderTaskName"
        worker = "Worker"

        expected_result = MagicMock(display=False)
        mock_export_task.objects.create.return_value = expected_result
        task_result = create_export_task_record(
            task_name=task_name,
            export_provider_task=export_provider_task_name,
            worker=worker,
            display=False)

        self.assertEquals(task_result, expected_result)
        mock_export_task.objects.create.assert_called_with(
            export_provider_task=export_provider_task_name,
            status=TaskStates.PENDING.value,
            name=task_name,
            worker=worker,
            display=False)

        expected_result = MagicMock(display=True)
        mock_export_task.objects.create.return_value = expected_result

        task_result = create_export_task_record(
            task_name=task_name,
            export_provider_task=export_provider_task_name,
            worker=worker,
            display=True)
        self.assertEquals(task_result, expected_result)
        mock_export_task.objects.create.assert_called_with(
            export_provider_task=export_provider_task_name,
            status=TaskStates.PENDING.value,
            name=task_name,
            worker=worker,
            display=True)

        mock_export_task.objects.create.side_effect = DatabaseError(
            "SomeError")
        with self.assertRaises(DatabaseError):
            create_export_task_record(
                task_name=task_name,
                export_provider_task=export_provider_task_name,
                worker=worker,
                display=True)
Ejemplo n.º 9
0
 def fetch(self, low_mark, high_mark):
     
     if self.root_predicate == None:
         raise DatabaseError('No root query node')
     
     try:
         if high_mark is not None and high_mark <= low_mark:
             return
         
         results = self._get_query_results()
         if low_mark is not None or high_mark is not None:
             results = results[low_mark:high_mark]
     except Exception, e:
         # FIXME: Can get rid of this exception handling code eventually,
         # but it's useful for debugging for now.
         #traceback.print_exc()
         raise e
Ejemplo n.º 10
0
    def make_result(self, entity, fields):
        result = []

        for field in fields:
            value = entity.get(field.column, NOT_PROVIDED)
            if value is NOT_PROVIDED:
                value = field.get_default()
            else:
                value = self.convert_value_from_db(
                    field.db_type(connection=self.connection), value)

            if not field.null and value is None:
                raise DatabaseError("Non-nullable field %s can't be None!" %
                                    field.name)

            result.append(value)
        return result
Ejemplo n.º 11
0
    def test_auditable_model_delete_with_database_error(self):
        luy = LearningUnitYearFactory()
        geys = [GroupElementYearFactory(child_leaf=luy) for i in range(20)]

        result = None
        with patch.object(AuditableModel, 'save') as mock_method:
            mock_method.side_effect = DatabaseError("test error")

            try:
                luy.delete()
            except DatabaseError as e:
                result = e

        self.assertIsInstance(result, DatabaseError)
        self.is_existing_for_orm(luy)
        for gey in geys:
            self.is_existing_for_orm(gey)
Ejemplo n.º 12
0
class CassandraConnection(object):
    def __init__(self, host, port, keyspace, username, password, pool_size=5):
        self.host = host
        self.port = port
        self.keyspace = keyspace
        self.username = username
        self.password = password
        self.pool_size = pool_size

        self.logged_in = False
        self.pool = None

    def commit(self):
        pass

    def open(self):
        server_list = [self.host + ":" + self.port]
        connected = False

        try:
            if self.username and self.password:
                credentials = {
                    'username': self.username,
                    'password': self.password
                }
                self.pool = ConnectionPool(keyspace=self.keyspace,
                                           server_list=server_list,
                                           credentials=credentials,
                                           pool_size=self.pool_size)
                if self.pool:
                    self.logged_in = True
                    connected = True
            else:
                self.pool = ConnectionPool(keyspace=self.keyspace,
                                           server_list=server_list,
                                           pool_size=self.pool_size)
                if self.pool:
                    connected = True

        except Exception, e:
            pass

        if not connected:
            raise DatabaseError('Error connecting to keyspace: %s; %s' %
                                (self.keyspace, str(e)))
Ejemplo n.º 13
0
 def login(self):
     # TODO: This user/password auth code hasn't been tested
     if not self.logged_in:
         if self.user:
             try:
                 if self.client:
                     credentials = {'username': self.user, 'password': self.password}
                     self.client.login(AuthenticationRequest(credentials))
                     self.logged_in = True
             except Exception, e:
                 # In this case we won't have set logged_in to true, so we'll throw the
                 # exception below where it also handles the case that self.client
                 # is not valid yet.
                 pass
             if not self.logged_in:
                 raise DatabaseError('Error logging in to keyspace: %s; %s' % (self.keyspace, str(e)))
         else:
             self.logged_in = True
Ejemplo n.º 14
0
    def _create_trigger(self, field):
        from django.db.utils import DatabaseError
        cursor = self.connection.cursor()

        opts = field.model._meta
        trigger_name = get_trigger_name(field, opts)

        stms = self.sql.split('##')
        for template in stms:
            stm = template.format(trigger_name=trigger_name,
                                  opts=opts,
                                  field=field)
            try:
                cursor.execute(stm)
            except BaseException as exc:
                raise DatabaseError(exc)

        return trigger_name
Ejemplo n.º 15
0
	def _get_s3_bucket(cls, bucket_name, assert_versioning_enabled):
		try:
			connection = cls._get_s3_connection()
			if not connection.lookup(bucket_name):
				connection.create_bucket(bucket_name)
			
			bucket = connection.get_bucket(bucket_name)
			
			if assert_versioning_enabled:
				cls._assert_bucket_has_versioning_enabled(bucket)
				
			return bucket
		except boto_exceptions.S3ResponseError as e:
			raise DatabaseError(
				"Error retrieving bucket from S3.\nBucket: {}\nBoto Exception:\n{}".format(
					bucket_name, e
				)
			)
Ejemplo n.º 16
0
    def test_scale_post_steps_database_error(self, mock_env_vars, mock_db,
                                             mock_sys_exit):
        """Tests executing scale_post_steps when a database error occurs."""

        # Set up mocks
        def get_env_vars(name, *args, **kwargs):
            return str(self.job.id) if name == 'SCALE_JOB_ID' else str(
                self.job_exe.exe_num)

        mock_env_vars.side_effect = get_env_vars
        mock_db.side_effect = DatabaseError()

        # Call method to test
        cmd = PostCommand()
        cmd.run_from_argv(['manage.py', 'scale_post_steps'])

        # Check results
        mock_sys_exit.assert_called_with(ScaleDatabaseError().exit_code)
Ejemplo n.º 17
0
 def test_raises_if_save_raises_database_error(self):
     mock_pod_form = Mock()
     self.mock_PodForm.return_value = mock_pod_form
     mock_pod_form.errors = {}
     mock_pod_form.is_valid = Mock()
     mock_pod_form.is_valid.return_value = True
     mock_pod_form.save = Mock()
     mock_pod_form.save.side_effect = DatabaseError("broken transaction")
     node = factory.make_Node_with_Interface_on_Subnet(
         status=NODE_STATUS.DEPLOYING,
         agent_name="maas-kvm-pod",
         install_kvm=True,
     )
     factory.make_StaticIPAddress(interface=node.boot_interface)
     NodeMetadata.objects.create(node=node,
                                 key="virsh_password",
                                 value="xyz123")
     self.assertRaises(DatabaseError, _create_pod_for_deployment, node)
Ejemplo n.º 18
0
	def _get_s3_connection(cls):
		s3_connection = getattr(thread_safe_connection_cache, 's3_connection', None)
		
		if s3_connection:
			return s3_connection
		
		aws_access_key_id = getattr(settings, 'AWS_S3_FILES_ACCESS_KEY_ID', None)
		aws_secret_access_key = getattr(settings, 'AWS_S3_FILES_SECRET_ACCESS_KEY', None)
		assert aws_access_key_id and aws_secret_access_key, \
			"Please assign values for AWS_S3_FILES_ACCESS_KEY_ID and AWS_S3_FILES_SECRET_ACCESS_KEY in settings"
		
		try:
			connection = S3Connection(aws_access_key_id, aws_secret_access_key) # TODO: We may want to move to a connection pool
			setattr(thread_safe_connection_cache, 's3_connection', connection)
		except boto_exceptions.BotoClientError as e:
			raise DatabaseError("Unable to connect to S3.\nBoto Exception:\n{}".format(e))
		
		return thread_safe_connection_cache.s3_connection
Ejemplo n.º 19
0
    def insert(self, docs, return_id=False):
        """
        Stores a document using field columns as element names, except
        for the primary key field for which "_id" is used.

        If just a {pk_field: None} mapping is given a new empty
        document is created, otherwise value for a primary key may not
        be None.
        """
        for doc in docs:
            try:
                doc['_id'] = doc.pop(self.query.get_meta().pk.column)
            except KeyError:
                pass
            if doc.get('_id', NOT_PROVIDED) is None:
                if len(doc) == 1:
                    # insert with empty model
                    doc.clear()
                else:
                    raise DatabaseError(
                        "Can't save entity with _id set to None")

        collection = self.get_collection()
        options = self.connection.operation_flags.get('save', {})
        # Solution to fix save is deprecated.
        # if id is in the doc, the data needs to be updated else data needs to be inserted
        try:
            doc['_id']
            is_update = True
            update_spec = {'$set': doc}
        except KeyError:
            is_update = False
        if return_id:
            if is_update:
                return collection.update_one({'_id': doc['_id']}, update_spec,
                                             True)
            else:
                return collection.insert_one(doc)
        else:
            if is_update:
                #return collection.save(doc, **options)
                collection.update_one({'_id': doc['_id']}, update_spec, True)
            else:
                collection.insert_one(doc)
Ejemplo n.º 20
0
    def _create_trigger(self, field):
        from django.db.utils import DatabaseError

        opts = field.model._meta
        trigger_name = get_trigger_name(field, opts)

        stm = self.sql.format(trigger_name=trigger_name,
                              opts=opts,
                              field=field)

        self.connection.drop_trigger('{}_i'.format(trigger_name))
        self.connection.drop_trigger('{}_u'.format(trigger_name))
        try:
            self.connection.cursor().execute(stm)
            self._triggers[field] = trigger_name
        except BaseException as exc:  # pragma: no cover
            raise DatabaseError(exc)

        return trigger_name
Ejemplo n.º 21
0
 def _add_filter(self, column, op, db_type, value):
     for query in self.gae_query:
         key = '%s %s' % (column, op)
         value = self.convert_value_for_db(db_type, value)
         if isinstance(value, Text):
             raise DatabaseError('TextField is not indexed, by default, '
                                 "so you can't filter on it. Please add "
                                 'an index definition for the column %s '
                                 'on the model %s.%s as described here:\n'
                                 'http://www.allbuttonspressed.com/blog/django/2010/07/Managing-per-field-indexes-on-App-Engine'
                                 % (column, self.query.model.__module__, self.query.model.__name__))
         if key in query:
             existing_value = query[key]
             if isinstance(existing_value, list):
                 existing_value.append(value)
             else:
                 query[key] = [existing_value, value]
         else:
             query[key] = value
Ejemplo n.º 22
0
    def check_query(self):
        """
        Checks if the current query is supported by the database.

        In general, we expect queries requiring JOINs (many-to-many
        relations, abstract model bases, or model spanning filtering),
        using DISTINCT (through `QuerySet.distinct()`, which is not
        required in most situations) or using the SQL-specific
        `QuerySet.extra()` to not work with nonrel back-ends.
        """
        if hasattr(self.query, 'is_empty') and self.query.is_empty():
            raise EmptyResultSet()
        if (len([
                a for a in self.query.alias_map if self.query.alias_refcount[a]
        ]) > 1 or self.query.distinct
                or self.query.extra):  # or self.having -- Not quite working.
            # having is no longer part of the query as of 1.9; It moved to the compiler
            # https://github.com/django/django/commit/afe0bb7b13bb8dc4370f32225238012c873b0ee3
            raise DatabaseError("This query is not supported by the database.")
Ejemplo n.º 23
0
    def sql_create_model(self, model, style, known_models=set()):

        db_connection = self.connection.db_connection
        keyspace = self.connection.settings_dict['NAME']

        opts = model._meta
        column_metadata = []

        # Browsing through fields to find indexed fields
        for field in opts.local_fields:
            if field.db_index:
                column_name = str(
                    field.db_column if field.db_column else field.column)
                column_def = ColumnDef(name=column_name,
                                       validation_class='BytesType',
                                       index_type=IndexType.KEYS)
                column_metadata.append(column_def)

        cfdef_settings = self.connection.column_family_def_defaults.copy()

        if hasattr(model, 'CassandraSettings') and \
            hasattr(model.CassandraSettings, 'COLUMN_FAMILY_DEF_SETTINGS'):
            cfdef_overrides = model.CassandraSettings.COLUMN_FAMILY_DEF_SETTINGS
            if type(cfdef_overrides) is not dict:
                raise DatabaseError(
                    'The value of COLUMN_FAMILY_DEF_SETTINGS in the '
                    'CassandraSettings class must be a dictionary of the optional '
                    'settings to use when creating the column family.')
            cfdef_settings.update(cfdef_overrides)

        cfdef_settings['keyspace'] = keyspace
        if not cfdef_settings.get('name'):
            cfdef_settings['name'] = opts.db_table
        if not cfdef_settings.get('comparator_type'):
            cfdef_settings['comparator_type'] = 'UTF8Type'
        cfdef_settings['column_metadata'] = column_metadata

        column_family_def = CfDef(**cfdef_settings)

        db_connection.get_client().system_add_column_family(column_family_def)

        return [], {}
Ejemplo n.º 24
0
def connect_to_db():
    try:
        keyspace = DATABASES['cassandra']['NAME']
        username = DATABASES['cassandra']['USER']
        password = DATABASES['cassandra']['PASSWORD']
        host = DATABASES['cassandra']['HOST']
        port = DATABASES['cassandra']['PORT']
        pool_size = DATABASES['cassandra']['POOL_SIZE']

        con = CassandraConnection(host,
                                  port,
                                  keyspace,
                                  username,
                                  password,
                                  pool_size=pool_size)

        return con
    except Exception, e:
        raise DatabaseError(
            'Error connecting to database. Incorrect configuration in settings file: %s'
            % str(e))
Ejemplo n.º 25
0
    def combine_duration_expression(self, connector, sub_expressions):
        """Combine duration expressions into single one using connector.

        :type connector: str
        :param connector: A type of connector operation.

        :type sub_expressions: list
        :param sub_expressions: A list of expressions to combine.

        :raises: :class:`~django.db.utils.DatabaseError`

        :rtype: str
        :return: A SQL statement for combining.
        """
        if connector == "+":
            return "TIMESTAMP_ADD(" + ", ".join(sub_expressions) + ")"
        elif connector == "-":
            return "TIMESTAMP_SUB(" + ", ".join(sub_expressions) + ")"
        else:
            raise DatabaseError("Invalid connector for timedelta: %s." %
                                connector)
Ejemplo n.º 26
0
    def _save(self, data, return_id=False):
        collection = self.get_collection()
        options = self.connection.operation_flags.get('save', {})

        # Check for fields set to None
        if None in data.values():
            # Check if we have null + unique fields set to None. If so delete
            # those from data, so that the sparse index works
            fields = self.get_fields()
            for field in fields:
                if field.null and field.unique and data[field.column] is None:
                    del data[field.column]

        if data.get('_id', NOT_PROVIDED) is None:
            if len(data) == 1:
                # insert with empty model
                data = {}
            else:
                raise DatabaseError("Can't save entity with _id set to None")
        primary_key = collection.save(data, **options)
        if return_id:
            return unicode(primary_key)
Ejemplo n.º 27
0
    def connect(self):

        super(DatabaseWrapper, self).connect()

        if not (self.connection is not None
                and self.django_pool_params.django_pre_ping):
            return

        is_usable = False
        ex_message = None
        ex_default = 'unable to connect to the database'
        try:
            is_usable = self.is_usable()  # ping
        except Exception as ex:
            ex_message = str(ex)
        finally:
            if not is_usable:
                try:
                    self.errors_occurred = True
                    self.close()
                finally:
                    raise DatabaseError(ex_message or ex_default)
Ejemplo n.º 28
0
 def get_fields(self):
     """
     Returns the fields which should get loaded from the backend by self.query
     """
     # We only set this up here because
     # related_select_fields isn't populated until
     # execute_sql() has been called.
     if self.query.select_fields:
         fields = self.query.select_fields + self.query.related_select_fields
     else:
         fields = self.query.model._meta.fields
     # If the field was deferred, exclude it from being passed
     # into `resolve_columns` because it wasn't selected.
     only_load = self.deferred_to_columns()
     if only_load:
         db_table = self.query.model._meta.db_table
         fields = [f for f in fields if db_table in only_load and
                   f.column in only_load[db_table]]
     for field in fields:
         if field.model._meta != self.query.model._meta:
             raise DatabaseError('Multi-table inheritance is not supported '
                                 'by non-relational DBs.')
     return fields
Ejemplo n.º 29
0
    def table_names(self):

        cursor = connection.cursor()
        try:
            # mysql
            campus_tables = "SELECT table_name \
                    FROM INFORMATION_SCHEMA.TABLES \
                    WHERE table_schema='%s' \
                    AND (LOCATE('campus_', table_name) = 1 OR LOCATE('south_', table_name) = 1)" % settings.DATABASES['default']['NAME']
            cursor.execute(campus_tables)
            return cursor
        except DatabaseError:
            pass

        try:
            # sqlite
            campus_tables = "SELECT name FROM sqlite_master WHERE type IN ('table','view') AND (name LIKE 'campus_%%' OR name LIKE 'south_%%')"
            cursor.execute(campus_tables)
            return cursor
        except DatabaseError:
            pass

        raise DatabaseError('Can not read table names from the database')
Ejemplo n.º 30
0
    def update(self, values):
        """
        Changes an entity that already exists in the database.

        :param values: A list of (field, new-value) pairs.
        """

        pool = self.connection
        column_family_name = get_column_family()
        col_fam = CF(pool, column_family_name)

        pk_column = get_pk_column()

        pk_index = -1
        fields = self.get_fields()

        for index in range(len(fields)):
            if fields[index].column == pk_column:
                pk_index = index
                break

        if pk_index == -1:
            raise DatabaseError('Invalid primary key column.')

        b = col_fam.batch(
            write_consistency_level=self.connection.write_consistency_level)
        row_count = 0
        for result in self.results_iter():
            row_count += 1
            key = result[pk_index]

            for k, v in values.items():
                b.insert(k, v)

        b.send()

        return row_count
Ejemplo n.º 31
0
 def _execute_raise_database_already_exists(self, cursor, parameters, keepdb=False):
     error = DatabaseError('database %s already exists' % parameters['dbname'])
     error.pgcode = errorcodes.DUPLICATE_DATABASE
     raise DatabaseError() from error
Ejemplo n.º 32
0
 def _execute_raise_permission_denied(self, cursor, parameters, keepdb=False):
     error = DatabaseError('permission denied to create database')
     error.pgcode = errorcodes.INSUFFICIENT_PRIVILEGE
     raise DatabaseError() from error