コード例 #1
0
    def set_name_with_model(self, model):
        """
        Generate a unique name for the index.

        The name is divided into 3 parts - table name (12 chars), field name
        (8 chars) and unique hash + suffix (10 chars). Each part is made to
        fit its size by truncating the excess length.
        """
        _, table_name = split_identifier(model._meta.db_table)
        column_names = [
            model._meta.get_field(field_name).column
            for field_name, order in self.fields_orders
        ]
        column_names_with_order = [
            (("-%s" if order else "%s") % column_name)
            for column_name, (field_name,
                              order) in zip(column_names, self.fields_orders)
        ]
        # The length of the parts of the name is based on the default max
        # length of 30 characters.
        hash_data = [table_name] + column_names_with_order + [self.suffix]
        self.name = "%s_%s_%s" % (
            table_name[:11],
            column_names[0][:7],
            "%s_%s" % (names_digest(*hash_data, length=6), self.suffix),
        )
        assert len(self.name) <= self.max_name_length, (
            "Index too long for multiple database support. Is self.suffix "
            "longer than 3 characters?")
        self.check_name()
コード例 #2
0
ファイル: indexes.py プロジェクト: GravyHands/django
    def set_name_with_model(self, model):
        """
        Generate a unique name for the index.

        The name is divided into 3 parts - table name (12 chars), field name
        (8 chars) and unique hash + suffix (10 chars). Each part is made to
        fit its size by truncating the excess length.
        """
        _, table_name = split_identifier(model._meta.db_table)
        column_names = [model._meta.get_field(field_name).column for field_name, order in self.fields_orders]
        column_names_with_order = [
            (('-%s' if order else '%s') % column_name)
            for column_name, (field_name, order) in zip(column_names, self.fields_orders)
        ]
        # The length of the parts of the name is based on the default max
        # length of 30 characters.
        hash_data = [table_name] + column_names_with_order + [self.suffix]
        self.name = '%s_%s_%s' % (
            table_name[:11],
            column_names[0][:7],
            '%s_%s' % (names_digest(*hash_data, length=6), self.suffix),
        )
        assert len(self.name) <= self.max_name_length, (
            'Index too long for multiple database support. Is self.suffix '
            'longer than 3 characters?'
        )
        self.check_name()
コード例 #3
0
ファイル: indexes.py プロジェクト: ateneva/softuni_proj
    def set_name_with_model(self, model):
        """
        Generate a unique name for the index.

        The name is divided into 3 parts - table name (12 chars), field name
        (8 chars) and unique hash + suffix (10 chars). Each part is made to
        fit its size by truncating the excess length.
        """
        _, table_name = split_identifier(model._meta.db_table)
        column_names = [model._meta.get_field(field_name).column for field_name, order in self.fields_orders]
        column_names_with_order = [
            (('-%s' if order else '%s') % column_name)
            for column_name, (field_name, order) in zip(column_names, self.fields_orders)
        ]
        # The length of the parts of the name is based on the default max
        # length of 30 characters.
        hash_data = [table_name] + column_names_with_order + [self.suffix]
        self.name = '%s_%s_%s' % (
            table_name[:11],
            column_names[0][:7],
            '%s_%s' % (names_digest(*hash_data, length=6), self.suffix),
        )
        if len(self.name) > self.max_name_length:
            raise ValueError(
                'Index too long for multiple database support. Is self.suffix '
                'longer than 3 characters?'
            )
        if self.name[0] == '_' or self.name[0].isdigit():
            self.name = 'D%s' % self.name[1:]
コード例 #4
0
ファイル: schema.py プロジェクト: sourya/django-1
    def _create_index_name(self, table_name, column_names, suffix=""):
        """
        Generate a unique name for an index/unique constraint.

        The name is divided into 3 parts: the table name, the column names,
        and a unique digest and suffix.
        """
        _, table_name = split_identifier(table_name)
        hash_suffix_part = '%s%s' % (names_digest(table_name, *column_names, length=8), suffix)
        max_length = self.connection.ops.max_name_length() or 200
        # If everything fits into max_length, use that name.
        index_name = '%s_%s_%s' % (table_name, '_'.join(column_names), hash_suffix_part)
        if len(index_name) <= max_length:
            return index_name
        # Shorten a long suffix.
        if len(hash_suffix_part) > max_length / 3:
            hash_suffix_part = hash_suffix_part[:max_length // 3]
        other_length = (max_length - len(hash_suffix_part)) // 2 - 1
        index_name = '%s_%s_%s' % (
            table_name[:other_length],
            '_'.join(column_names)[:other_length],
            hash_suffix_part,
        )
        # Prepend D if needed to prevent the name from starting with an
        # underscore or a number (not permitted on Oracle).
        if index_name[0] == "_" or index_name[0].isdigit():
            index_name = "D%s" % index_name[:-1]
        return index_name
コード例 #5
0
ファイル: db.py プロジェクト: beanbaginc/django-evolution
def digest(connection, *args):
    """Return a digest hash for a set of arguments.

    This is mostly used as part of the index/constraint name generation
    processes. It offers compatibility with a range of Django versions.

    Args:
        connection (object):
            The database connection.

        *args (tuple):
            The positional arguments used to build the digest hash out of.

    Returns:
        str:
        The resulting digest hash.
    """
    if names_digest is not None:
        # Django >= 2.2
        return names_digest(args[0], *args[1:], length=8)
    elif (BaseDatabaseSchemaEditor
          and hasattr(BaseDatabaseSchemaEditor, '_digest')):
        # Django >= 1.8, < 2.2
        #
        # Note that _digest() is a classmethod that is common across all
        # database backends. We don't need to worry about using a
        # per-instance version. If that changes, we'll need to create a
        # SchemaEditor.
        return BaseDatabaseSchemaEditor._digest(*args)
    else:
        # Django < 1.8
        return connection.creation._digest(*args)
コード例 #6
0
    def _sql_indexes_for_field(self, model, field):
        """
        Return the CREATE INDEX SQL statements for a single model field

        :param model:
        :param field:
        :return:
        """
        def qn(name):
            if name.startswith('"') and name.endswith('"'):
                return name  # Quoting once is enough.
            return '"%s"' % name

        max_name_length = 63

        if field.db_index and not field.unique:
            i_name = names_digest(model._meta.db_table, field.column, length=8)
            return [
                "CREATE INDEX %s ON %s(%s)" % (
                    qn(truncate_name(i_name, max_name_length)),
                    qn(model._meta.db_table),
                    qn(field.column),
                )
            ]
        return []
コード例 #7
0
ファイル: __init__.py プロジェクト: tiagodread/awx
    import django  # noqa: F401

    HAS_DJANGO = True
except ImportError:
    HAS_DJANGO = False
else:
    from django.db.backends.base import schema
    from django.db.models import indexes
    from django.db.backends.utils import names_digest
    from django.db import connection

if HAS_DJANGO is True:

    # See upgrade blocker note in requirements/README.md
    try:
        names_digest('foo', 'bar', 'baz', length=8)
    except ValueError:

        def names_digest(*args, length):
            """
            Generate a 32-bit digest of a set of arguments that can be used to shorten
            identifying names.  Support for use in FIPS environments.
            """
            h = hashlib.md5(usedforsecurity=False)
            for arg in args:
                h.update(arg.encode())
            return h.hexdigest()[:length]

        schema.names_digest = names_digest
        indexes.names_digest = names_digest
コード例 #8
0
ファイル: fields.py プロジェクト: SideMoney/django-pgjsonb
    def create_jsonb_index_sql(editor, model, field):
        options = field.db_index_options

        json_path_op = "->"
        sqls = {}
        for option in options:
            paths = option.get("path", "")
            if not paths:
                path = "%(columns)s"
            else:
                path_elements = paths.split("__")
                path = "(%(columns)s{}{})".format(json_path_op, json_path_op.join(["'%s'" % element for element in path_elements]))

            ops_cls = " jsonb_path_ops" if option.get("only_contains") else ""
            sql = editor.create_jsonb_index_sql.format(path=path, ops_cls=ops_cls)
            sqls[get_jsonb_index_name(editor, model, field, option)] = editor._create_index_sql(model, [field], sql=sql, suffix=(names_digest(paths, length=8) if paths else ""))
        return sqls
コード例 #9
0
ファイル: fields.py プロジェクト: SideMoney/django-pgjsonb
 def get_jsonb_index_name(editor, model, field, index_info):
     return editor._create_index_name(model.__name__, [field.name], suffix=names_digest(index_info.get("path") or "", length=8))
コード例 #10
0
ファイル: indexes.py プロジェクト: aropan/clist
 def set_name_with_model(self, model):
     self.fields_orders = [(model._meta.pk.name, '')]
     _, table_name = split_identifier(model._meta.db_table)
     digest = names_digest(table_name, *self.fields, length=6)
     self.name = f"{table_name[:19]}_{digest}_{self.suffix}"