def rename_column(self, model, old_field, new_field):
        if old_field.column == new_field.column:
            # No Operation
            return []

        qn = self.connection.ops.quote_name
        max_name_length = self.connection.ops.max_name_length()
        opts = model._meta
        refs = {}
        models = []

        return AlterTableSQLResult(
            self,
            model,
            pre_sql=self.remove_field_constraints(old_field, opts, models,
                                                  refs),
            alter_table=[
                {
                    'independent': True,
                    'sql': 'RENAME COLUMN %s TO %s'
                           % (truncate_name(qn(old_field.column),
                                            max_name_length),
                              truncate_name(qn(new_field.column),
                                            max_name_length)),
                },
            ],
            post_sql=self.add_primary_key_field_constraints(
                old_field, new_field, models, refs)
        )
Example #2
0
    def sql_indexes_for_field(self, model, f, style):
        """
        Create a CREATE INDEX sentence for  custom fields.
        """
        from django_orm.fields import standard as stdfields
        kwargs = VERSION[:2] >= (1, 3) and {'connection': self.connection} or {}

        if f.db_type(**kwargs) in ('hstore', 'tsvector'):
            if not f.db_index:
                return []

            # create GIST index for hstore column
            qn = self.connection.ops.quote_name
            index_name = '%s_%s_gist' % (model._meta.db_table, f.column)
            clauses = [style.SQL_KEYWORD('CREATE INDEX'),
                style.SQL_TABLE(qn(truncate_name(index_name, self.connection.ops.max_name_length()))),
                style.SQL_KEYWORD('ON'),
                style.SQL_TABLE(qn(model._meta.db_table)),
                style.SQL_KEYWORD('USING GIST'),
                '(%s)' % style.SQL_FIELD(qn(f.column))]

            # add tablespace clause
            tablespace = f.db_tablespace or model._meta.db_tablespace
            if tablespace:
                sql = self.connection.ops.tablespace_sql(tablespace)
                if sql:
                    clauses.append(sql)

            clauses.append(';')
            return [' '.join(clauses)]

        elif isinstance(f, stdfields.CharField):
            if not f.db_index:
                return []

            output = super(DatabaseCreation, self).sql_indexes_for_field(model, f, style)
            qn = self.connection.ops.quote_name

            index_name0 = '%s_%s_idx%s_btree' % (model._meta.db_table, f.column, 0)
            index_name1 = '%s_%s_idx%s_btree' % (model._meta.db_table, f.column, 1)

            clauses0 = [style.SQL_KEYWORD('CREATE INDEX'),
                style.SQL_TABLE(qn(truncate_name(index_name0, self.connection.ops.max_name_length()))),
                style.SQL_KEYWORD('ON'),
                style.SQL_TABLE(qn(model._meta.db_table)),
                style.SQL_KEYWORD('USING BTREE'),
                '(unaccent(%s))' % style.SQL_FIELD(qn(f.column))]

            clauses1 = [style.SQL_KEYWORD('CREATE INDEX'),
                style.SQL_TABLE(qn(truncate_name(index_name1, self.connection.ops.max_name_length()))),
                style.SQL_KEYWORD('ON'),
                style.SQL_TABLE(qn(model._meta.db_table)),
                style.SQL_KEYWORD('USING BTREE'),
                '(lower(unaccent(%s)))' % style.SQL_FIELD(qn(f.column))]

            return output + [' '.join(clauses0) + ';'] + [' '.join(clauses1) + ';']
        return super(DatabaseCreation, self).sql_indexes_for_field(model, f, style)
Example #3
0
    def sql_indexes_for_field(self, model, f, style):
        """Return the CREATE INDEX SQL statements for a single model field"""
        output = []
        qn = self.connection.ops.quote_name
        max_name_length = self.connection.ops.max_name_length()
        # ignore tablespace information
        tablespace_sql = ''
        i = 0
        if getattr(self.connection.connection, dbms_name) != 'DB2':
            if len(model._meta.unique_together_index) != 0:
                for unique_together_index in model._meta.unique_together_index:
                    i += 1
                    column_list = []
                    for column in unique_together_index:
                        for local_field in model._meta.local_fields:
                            if column == local_field.name:
                                column_list.extend([local_field.column])

                    self.__add_psudokey_column(style, self.connection.cursor(), model._meta.db_table,
                                               model._meta.pk.attname, column_list)
                    column_list.extend(
                        [truncate_name("%s%s" % ( self.psudo_column_prefix, "_".join(column_list) ), max_name_length)])
                    output.extend([style.SQL_KEYWORD('CREATE UNIQUE INDEX') + ' ' + \
                                   style.SQL_TABLE(qn('db2_%s_%s' % ( model._meta.db_table, i ))) + ' ' + \
                                   style.SQL_KEYWORD('ON') + ' ' + \
                                   style.SQL_TABLE(qn(model._meta.db_table)) + ' ' + \
                                   '( %s )' % ", ".join(column_list) + ' ' + \
                                   '%s;' % tablespace_sql])
                model._meta.unique_together_index = []

            if f.unique_index:
                column_list = []
                column_list.extend([f.column])
                self.__add_psudokey_column(style, self.connection.cursor(), model._meta.db_table,
                                           model._meta.pk.attname, column_list)
                cisql = 'CREATE UNIQUE INDEX'
                output.extend([style.SQL_KEYWORD(cisql) + ' ' +
                               style.SQL_TABLE(qn('%s_%s' % ( model._meta.db_table, f.column ))) + ' ' +
                               style.SQL_KEYWORD('ON') + ' ' +
                               style.SQL_TABLE(qn(model._meta.db_table)) + ' ' +
                               "(%s, %s )" % (style.SQL_FIELD(qn(f.column)), style.SQL_FIELD(
                                   qn(truncate_name(( self.psudo_column_prefix + f.column ), max_name_length))) ) +
                               "%s;" % tablespace_sql])
                return output

        if f.db_index and not f.unique:
            cisql = 'CREATE INDEX'
            output.extend([style.SQL_KEYWORD(cisql) + ' ' +
                           style.SQL_TABLE(qn('%s_%s' % ( model._meta.db_table, f.column ))) + ' ' +
                           style.SQL_KEYWORD('ON') + ' ' +
                           style.SQL_TABLE(qn(model._meta.db_table)) + ' ' +
                           "(%s)" % style.SQL_FIELD(qn(f.column)) +
                           "%s;" % tablespace_sql])

        return output
Example #4
0
def sql_for_pending_references(self, model, style, pending_references):
    "Returns any ALTER TABLE statements to add constraints after the fact."
    from django.db.backends.util import truncate_name

    if not model._meta.managed or model._meta.proxy:
        return []
    qn = self.connection.ops.quote_name
    final_output = []
    opts = model._meta
    if model in pending_references:
        for rel_class, f in pending_references[model]:
            rel_opts = rel_class._meta
            r_table = rel_opts.db_table
            r_col = f.column
            table = opts.db_table
            col = opts.get_field(f.rel.field_name).column

            if not hasattr(col, "columns"):
                # For MySQL, r_name must be unique in the first 64 characters.
                # So we are careful with character usage here.
                r_name = "%s_refs_%s_%s" % (r_col, col, self._digest(r_table, table))
                final_output.append(
                    style.SQL_KEYWORD("ALTER TABLE")
                    + " %s ADD CONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s (%s)%s;"
                    % (
                        qn(r_table),
                        qn(truncate_name(r_name, self.connection.ops.max_name_length())),
                        qn(r_col),
                        qn(table),
                        qn(col),
                        self.connection.ops.deferrable_sql(),
                    )
                )
            else:
                try:
                    r_col = "_".join(cf.column for cf in f.fields)
                    col = "_".join(cf.column for cf in opts.pk.fields)
                    r_name = "%s_refs_%s_%s" % (r_col, col, self._digest(r_table, table))
                    final_output.append(
                        style.SQL_KEYWORD("ALTER TABLE")
                        + " %s ADD CONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s (%s)%s;"
                        % (
                            qn(r_table),
                            qn(truncate_name(r_name, self.connection.ops.max_name_length())),
                            ", ".join([style.SQL_FIELD(qn(cf.column)) for cf in f.fields]),
                            qn(table),
                            ", ".join([style.SQL_FIELD(qn(cf.column)) for cf in opts.pk.fields]),
                            self.connection.ops.deferrable_sql(),
                        )
                    )
                except:
                    print "Skip constraint: TODO", rel_class, model
        del pending_references[model]
    return final_output
Example #5
0
    def rename_column(self, opts, old_field, new_field):
        if old_field.column == new_field.column:
            # No Operation
            return []

        style = color.no_style()
        qn = self.connection.ops.quote_name
        max_name_length = self.connection.ops.max_name_length()
        creation = self.connection.creation
        sql = []
        refs = {}
        models = []

        if old_field.primary_key:
            for field in opts.local_many_to_many:
                if field.rel and field.rel.through:
                    through = field.rel.through

                    for m2m_f in through._meta.local_fields:
                        if (m2m_f.rel and
                            m2m_f.rel.to._meta.db_table == opts.db_table and
                            m2m_f.rel.field_name == old_field.column):

                            models.append(m2m_f.rel.to)
                            refs.setdefault(m2m_f.rel.to, []).append(
                                (through, m2m_f))

            remove_refs = refs.copy()

            for relto in models:
                sql.extend(creation.sql_remove_table_constraints(
                    relto, remove_refs, style))

        params = (qn(opts.db_table),
                  truncate_name(qn(old_field.column), max_name_length),
                  truncate_name(qn(new_field.column), max_name_length))
        sql.append('ALTER TABLE %s RENAME COLUMN %s TO %s;' % params)

        if old_field.primary_key:
            for relto in models:
                for rel_class, f in refs[relto]:
                    f.rel.field_name = new_field.column

                del relto._meta._fields[old_field.name]
                relto._meta._fields[new_field.name] = new_field

                sql.extend(creation.sql_for_pending_references(
                    relto, style, refs))

        return sql
Example #6
0
    def rename_column(self, opts, old_field, new_field):
        if old_field.column == new_field.column:
            # No Operation
            return []

        style = color.no_style()
        qn = self.connection.ops.quote_name
        max_name_length = self.connection.ops.max_name_length()
        creation = self.connection.creation
        sql = []
        refs = {}
        models = []

        if old_field.primary_key:
            for field in opts.local_many_to_many:
                if field.rel and field.rel.through:
                    through = field.rel.through

                    for m2m_f in through._meta.local_fields:
                        if (m2m_f.rel and
                            m2m_f.rel.to._meta.db_table == opts.db_table and
                            m2m_f.rel.field_name == old_field.column):

                            models.append(m2m_f.rel.to)
                            refs.setdefault(m2m_f.rel.to, []).append(
                                (through, m2m_f))

            remove_refs = refs.copy()

            for relto in models:
                sql.extend(creation.sql_remove_table_constraints(
                    relto, remove_refs, style))

        params = (qn(opts.db_table),
                  truncate_name(qn(old_field.column), max_name_length),
                  truncate_name(qn(new_field.column), max_name_length))
        sql.append('ALTER TABLE %s RENAME COLUMN %s TO %s;' % params)

        if old_field.primary_key:
            for relto in models:
                for rel_class, f in refs[relto]:
                    f.rel.field_name = new_field.column

                del relto._meta._fields[old_field.name]
                relto._meta._fields[new_field.name] = new_field

                sql.extend(creation.sql_for_pending_references(
                    relto, style, refs))

        return sql
Example #7
0
    def sql_for_pending_references(self, model, style, pending_references):
        """
        Returns any ALTER TABLE statements to add constraints after the fact.
        """
        # Code copied from django.db.backends.creation.BaseDatabaseCreation in Django 1.6.0.

        # We always need to create every ForeignKey reference,
        # so no need to check _create_for_schema()
        opts = model._meta
        if not opts.managed or opts.swapped:
            return []
        qn = self.connection.ops.quote_name
        final_output = []
        if model in pending_references:
            for rel_class, f in pending_references[model]:
                rel_opts = rel_class._meta
                r_table = rel_opts.db_table
                r_col = f.column
                table = opts.db_table
                col = opts.get_field(f.rel.field_name).column
                # For MySQL, r_name must be unique in the first 64 characters.
                # So we are careful with character usage here.
                r_name = '%s_refs_%s_%s' % (
                    r_col, col, self._digest(r_table, table))
                final_output.append(style.SQL_KEYWORD('ALTER TABLE') +
                    ' %s%s ADD CONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s%s (%s)%s;' %
                    (self._table_prefix(rel_class), qn(r_table), qn(truncate_name(
                        r_name, self.connection.ops.max_name_length())),
                    qn(r_col), self._table_prefix(model), qn(table), qn(col),
                    self.connection.ops.deferrable_sql()))
            del pending_references[model]
        return final_output
Example #8
0
    def sql_for_pending_references(self, model, style, pending_references):
        from django.db.backends.util import truncate_name

        opts = model._meta
        if not opts.managed or opts.proxy or opts.swapped:
            return []
        qn = self.connection.ops.quote_name
        final_output = []
        if model in pending_references:
            for rel_class, f in pending_references[model]:
                rel_opts = rel_class._meta
                r_table = rel_opts.db_table
                r_col = f.column
                table = opts.db_table
                col = opts.get_field(f.rel.field_name).column
                r_name = '%s_refs_%s_%s' % (
                    r_col, col, self._digest(r_table, table))
                final_output.append(style.SQL_KEYWORD('ALTER TABLE') +
                    ' %s ADD CONSTRAINT FOREIGN KEY (%s) REFERENCES %s (%s)%s CONSTRAINT %s;' %
                    (qn(r_table), 
                    qn(r_col), qn(table), qn(col),
                    self.connection.ops.deferrable_sql(),
                    qn(truncate_name(
                        r_name, self.connection.ops.max_name_length()))))
            del pending_references[model]
        return final_output 
Example #9
0
    def get_default_index_name(self, table_name, field):
        """Returns a default index name for the database.

        This will return an index name for the given field that matches what
        the database or Django database backend would automatically generate
        when marking a field as indexed or unique.

        This can be overridden by subclasses if the database or Django
        database backend provides different values.
        """
        assert field.unique or field.db_index

        if field.unique:
            index_name = field.column
        elif field.db_index:
            # This whole block of logic comes from sql_indexes_for_field
            # in django.db.backends.creation, and is designed to match
            # the logic for the past few versions of Django.
            if supports_index_together:
                # Starting in Django 1.5, the _digest is passed a raw
                # list. While this is probably a bug (digest should
                # expect a string), we still need to retain
                # compatibility. We know this behavior hasn't changed
                # as of Django 1.6.1.
                #
                # It also uses the field name, and not the column name.
                column = [field.name]
            else:
                column = field.column

            column = self.connection.creation._digest(column)
            index_name = '%s_%s' % (table_name, column)

        return truncate_name(index_name, self.connection.ops.max_name_length())
Example #10
0
def deferred_class_factory(model, attrs, bulk_attrs):
    """
    Returns a class object that is a copy of "model" with the specified "attrs"
    being replaced with BulkDeferredAttribute objects. The "pk_value" ties the
    deferred attributes to a particular instance of the model.
    """
    class Meta:
        proxy = True
        app_label = model._meta.app_label

    # The app_cache wants a unique name for each model, otherwise the new class
    # won't be created (we get an old one back). Therefore, we generate the
    # name using the passed in attrs. It's OK to reuse an existing class
    # object if the attrs are identical.
    name = "%s_Deferred_%s" % (model.__name__, '_'.join(sorted(list(attrs | bulk_attrs))))
    name = util.truncate_name(name, 80, 32)

    overrides = dict([(attr, BulkDeferredAttribute(attr, model))
            for attr in bulk_attrs - attrs])
    overrides.update(dict([(attr, DeferredAttribute(attr, model))
            for attr in attrs]))
    overrides["Meta"] = Meta
    overrides["__module__"] = model.__module__
    overrides["_deferred"] = True
    return type(name, (model,), overrides)
Example #11
0
def sql_for_pending_references(model, style, pending_references):
    """
    Returns any ALTER TABLE statements to add constraints after the fact.
    """
    from django.db import connection
    from django.db.backends.util import truncate_name

    qn = connection.ops.quote_name
    final_output = []
    if connection.features.supports_constraints:
        opts = model._meta
        if model in pending_references:
            for rel_class, f in pending_references[model]:
                rel_opts = rel_class._meta
                r_table = rel_opts.db_table
                r_col = f.column
                table = opts.db_table
                col = opts.get_field(f.rel.field_name).column
                # For MySQL, r_name must be unique in the first 64 characters.
                # So we are careful with character usage here.
                r_name = "%s_refs_%s_%x" % (r_col, col, abs(hash((r_table, table))))
                final_output.append(
                    style.SQL_KEYWORD("ALTER TABLE")
                    + " %s ADD CONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s (%s)%s;"
                    % (
                        qn(r_table),
                        truncate_name(r_name, connection.ops.max_name_length()),
                        qn(r_col),
                        qn(table),
                        qn(col),
                        connection.ops.deferrable_sql(),
                    )
                )
            del pending_references[model]
    return final_output
Example #12
0
 def sql_indexes_for_field(self, model, f, style):
     kwargs = VERSION[:2] >= (1, 3) and {"connection": self.connection} or {}
     if f.db_type(**kwargs) == "hstore":
         if not f.db_index:
             return []
         # create GIST index for hstore column
         qn = self.connection.ops.quote_name
         index_name = "%s_%s_gist" % (model._meta.db_table, f.column)
         clauses = [
             style.SQL_KEYWORD("CREATE INDEX"),
             style.SQL_TABLE(qn(truncate_name(index_name, self.connection.ops.max_name_length()))),
             style.SQL_KEYWORD("ON"),
             style.SQL_TABLE(qn(model._meta.db_table)),
             style.SQL_KEYWORD("USING GIST"),
             "(%s)" % style.SQL_FIELD(qn(f.column)),
         ]
         # add tablespace clause
         tablespace = f.db_tablespace or model._meta.db_tablespace
         if tablespace:
             sql = self.connection.ops.tablespace_sql(tablespace)
             if sql:
                 clauses.append(sql)
         clauses.append(";")
         return [" ".join(clauses)]
     return super(DatabaseCreation, self).sql_indexes_for_field(model, f, style)
Example #13
0
    def sql_indexes_for_field(self, model, f, style):
        kwargs = VERSION[:2] >= (1, 3) and {'connection': self.connection} or {}
        if f.db_type(**kwargs) == 'hstore':
            if not f.db_index:
                return []

            # create GIST index for hstore column
            qn = self.connection.ops.quote_name
            index_name = '%s_%s_gist' % (model._meta.db_table, f.column)
            clauses = [style.SQL_KEYWORD('CREATE INDEX'),
                style.SQL_TABLE(qn(truncate_name(index_name, self.connection.ops.max_name_length()))),
                style.SQL_KEYWORD('ON'),
                style.SQL_TABLE(qn(model._meta.db_table)),
                style.SQL_KEYWORD('USING GIST'),
                '(%s)' % style.SQL_FIELD(qn(f.column))]

            # add tablespace clause
            tablespace = f.db_tablespace or model._meta.db_tablespace
            if tablespace:
                sql = self.connection.ops.tablespace_sql(tablespace)
                if sql:
                    clauses.append(sql)
            clauses.append(';')
            return [ ' '.join(clauses) ]
        return super(DatabaseCreation, self).sql_indexes_for_field(model, f, style)
Example #14
0
    def sql_destroy_indexes_for_fields(self, model, fields, style):
        if len(fields) == 1 and fields[0].db_tablespace:
            tablespace_sql = self.connection.ops.tablespace_sql(
                fields[0].db_tablespace)
        elif model._meta.db_tablespace:
            tablespace_sql = self.connection.ops.tablespace_sql(
                model._meta.db_tablespace)
        else:
            tablespace_sql = ""
        if tablespace_sql:
            tablespace_sql = " " + tablespace_sql

        field_names = []
        qn = self.connection.ops.quote_name
        for f in fields:
            field_names.append(style.SQL_FIELD(qn(f.column)))

        index_name = "%s_%s" % (model._meta.db_table,
                                self._digest([f.name for f in fields]))

        from django.db.backends.util import truncate_name

        return [
            style.SQL_KEYWORD("DROP INDEX") + " " + style.SQL_TABLE(
                qn(
                    truncate_name(index_name,
                                  self.connection.ops.max_name_length()))) +
            " " + style.SQL_KEYWORD("ON") + " " +
            style.SQL_TABLE(qn(model._meta.db_table)) + ";",
        ]
Example #15
0
    def sql_destroy_indexes_for_fields(self, model, fields, style):
        # Django 1.6
        if len(fields) == 1 and fields[0].db_tablespace:
            tablespace_sql = self.connection.ops.tablespace_sql(
                fields[0].db_tablespace)
        elif model._meta.db_tablespace:
            tablespace_sql = self.connection.ops.tablespace_sql(
                model._meta.db_tablespace)
        else:
            tablespace_sql = ""
        if tablespace_sql:
            tablespace_sql = " " + tablespace_sql

        field_names = []
        qn = self.connection.ops.quote_name
        for f in fields:
            field_names.append(style.SQL_FIELD(qn(f.column)))

        index_name = "{0}_{1}".format(model._meta.db_table,
                                      self._digest([f.name for f in fields]))

        return [
            style.SQL_KEYWORD("DROP INDEX") + " " +
            style.SQL_TABLE(qn(truncate_name(index_name,
                self.connection.ops.max_name_length()))) + " " +
            style.SQL_KEYWORD("ON") + " " +
            style.SQL_TABLE(qn(model._meta.db_table)) + ";",
        ]
Example #16
0
 def get_index_sql(index_name, opclass=''):
     return (style.SQL_KEYWORD('CREATE INDEX') + ' ' +
             style.SQL_TABLE(qn(truncate_name(index_name,self.connection.ops.max_name_length()))) + ' ' +
             style.SQL_KEYWORD('ON') + ' ' +
             style.SQL_TABLE(qn(db_table)) + ' ' +
             "(%s%s)" % (style.SQL_FIELD(qn(f.column)), opclass) +
             "%s;" % tablespace_sql)
Example #17
0
 def sql_for_pending_references(self, model, style, pending_references):
     """
     Returns any ALTER TABLE statements to add constraints after the fact.
     """
     opts = model._meta
     if not opts.managed or opts.proxy or opts.swapped:
         return []
     qn = self.connection.ops.quote_name
     final_output = []
     if model in pending_references:
         for rel_class, f in pending_references[model]:
             rel_opts = rel_class._meta
             r_table = rel_opts.db_table
             r_col = f.column
             table = opts.db_table
             col = opts.get_field(f.rel.field_name).column
             # For MySQL, r_name must be unique in the first 64 characters.
             # So we are careful with character usage here.
             r_name = '%s_refs_%s_%s' % (
                 r_col, col, self._digest(r_table, table))
             if f.rel.on_delete == models.CASCADE:
                 cascade = ' ON DELETE CASCADE '
             else:
                 cascade = ''
             final_output.append(style.SQL_KEYWORD('ALTER TABLE') +
                 ' %s ADD CONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s (%s)%s%s;' %
                 (qn(r_table), qn(truncate_name(
                     r_name, self.connection.ops.max_name_length())),
                 qn(r_col), qn(table), qn(col),
                 cascade,
                 self.connection.ops.deferrable_sql()))
         del pending_references[model]
     return final_output
Example #18
0
    def sql_for_pending_references(self, model, style, pending_references):
        "Returns any ALTER TABLE statements to add constraints after the fact."
        from django.db.backends.util import truncate_name

        if not model._meta.managed or model._meta.proxy:
            return []
        qn = self.connection.ops.quote_name
        final_output = []
        opts = model._meta
        if model in pending_references:
            for rel_class, f in pending_references[model]:
                rel_opts = rel_class._meta
                r_table = rel_opts.db_table
                r_col = f.column
                table = opts.db_table
                col = opts.get_field(f.rel.field_name).column
                # For MySQL, r_name must be unique in the first 64 characters.
                # So we are careful with character usage here.
                r_name = '%s_refs_%s_%s' % (r_col, col,
                                            self._digest(r_table, table))
                final_output.append(style.SQL_KEYWORD('ALTER TABLE') + ' %s ADD CONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s (%s)%s;' % \
                    (qn(r_table), qn(truncate_name(r_name, self.connection.ops.max_name_length())),
                    qn(r_col), qn(table), qn(col),
                    self.connection.ops.deferrable_sql()))
            del pending_references[model]
        return final_output
Example #19
0
 def get_index_sql(index_name, opclass=''):
     return (style.SQL_KEYWORD('CREATE INDEX') + ' ' +
             style.SQL_TABLE(qn(truncate_name(index_name,self.connection.ops.max_name_length()))) + ' ' +
             style.SQL_KEYWORD('ON') + ' ' +
             style.SQL_TABLE(qn(db_table)) + ' ' +
             "(%s%s)" % (style.SQL_FIELD(qn(f.column)), opclass) +
             "%s;" % tablespace_sql)
Example #20
0
    def sql_indexes_for_field(self, model, f, style):
        "Return the CREATE INDEX SQL statements for a single model field"
        from django.db.backends.util import truncate_name

        if f.db_index and not f.unique:
            qn = self.connection.ops.quote_name
            tablespace = f.db_tablespace or model._meta.db_tablespace
            if tablespace:
                sql = self.connection.ops.tablespace_sql(tablespace)
                if sql:
                    tablespace_sql = ' ' + sql
                else:
                    tablespace_sql = ''
            else:
                tablespace_sql = ''
            i_name = '%s_%s' % (model._meta.db_table, self._digest(f.column))
            output = [
                style.SQL_KEYWORD('CREATE INDEX') + ' ' + style.SQL_TABLE(
                    qn(
                        truncate_name(
                            i_name, self.connection.ops.max_name_length()))) +
                ' ' + style.SQL_KEYWORD('ON') + ' ' +
                style.SQL_TABLE(qn(model._meta.db_table)) + ' ' +
                "(%s)" % style.SQL_FIELD(qn(f.column)) + "%s;" % tablespace_sql
            ]
        else:
            output = []
        return output
Example #21
0
    def sql_remove_table_constraints(self, model, references_to_delete, style):

        from django.db.backends.util import truncate_name

        if not model._meta.managed or model._meta.proxy or model._meta.swapped:
            return []

        output = []

        qn = self.connection.ops.quote_name ''

        for rel_class, f in references_to_delete[model]:
            table = rel_class._meta.db_table
            col = f.column
            r_table = model._meta.db_table
            r_col = model._meta.get_field(f.rel.field_name).column

            r_name = '%s_refs_%s_%s' % (
                col, r_col, self._digest(table, r_table))

            output.append('%s %s %s %s;' % \
                (style.SQL_KEYWORD('ALTER TABLE'),
                style.SQL_TABLE(qn(table)),
                style.SQL_KEYWORD(self.connection.ops.drop_foreignkey_sql()),
                style.SQL_FIELD(qn(truncate_name(
                    r_name, self.connection.ops.max_name_length())))))

        del references_to_delete[model] 在引用列表中删除
        return output
Example #22
0
 def sql_indexes_for_field(self, model, f, style):
     kwargs = VERSION[:2] >= (1, 3) and {
         'connection': self.connection
     } or {}
     if f.db_type(**kwargs) == 'hstore':
         if not f.db_index:
             return []
         # create GIST index for hstore column
         qn = self.connection.ops.quote_name
         index_name = '%s_%s_gist' % (model._meta.db_table, f.column)
         clauses = [
             style.SQL_KEYWORD('CREATE INDEX'),
             style.SQL_TABLE(
                 qn(
                     truncate_name(index_name,
                                   self.connection.ops.max_name_length()))),
             style.SQL_KEYWORD('ON'),
             style.SQL_TABLE(qn(model._meta.db_table)),
             style.SQL_KEYWORD('USING GIST'),
             '(%s)' % style.SQL_FIELD(qn(f.column))
         ]
         # add tablespace clause
         tablespace = f.db_tablespace or model._meta.db_tablespace
         if tablespace:
             sql = self.connection.ops.tablespace_sql(tablespace)
             if sql:
                 clauses.append(sql)
         clauses.append(';')
         return [' '.join(clauses)]
     return super(DatabaseCreation,
                  self).sql_indexes_for_field(model, f, style)
Example #23
0
    def sql_for_pending_references(self, model, style, pending_references):
        """
        Returns any ALTER TABLE statements to add constraints after the fact.
        pg_django adds ON DELETE CASCADE if settings.DELETE_CASCADE is True
        """
        from django.db.backends.util import truncate_name
        from django.db.models import CASCADE

        if not model._meta.managed or model._meta.proxy:
            return []
        qn = self.connection.ops.quote_name
        final_output = []
        opts = model._meta
        if model in pending_references:
            for rel_class, f in pending_references[model]:
                if getattr(settings, 'DB_CASCADE', False
                          )and f.rel.on_delete == CASCADE:
                    cascade = ' ON DELETE CASCADE'
                else:
                    cascade = ''
                rel_opts = rel_class._meta
                r_table = rel_opts.db_table
                r_col = f.column
                table = opts.db_table
                col = opts.get_field(f.rel.field_name).column
                r_name = '%s_refs_%s_%s' % (
                    r_col, col, self._digest(r_table, table))
                final_output.append(style.SQL_KEYWORD('ALTER TABLE') +
                    ' %s ADD CONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s (%s)%s%s;' %
                    (qn(r_table), qn(truncate_name(
                        r_name, self.connection.ops.max_name_length())),
                    qn(r_col), qn(table), qn(col), cascade,
                    self.connection.ops.deferrable_sql()))
            del pending_references[model]
        return final_output
Example #24
0
    def sql_indexes_for_field(self, model, f, style):
        "Return the CREATE INDEX SQL statements for a single model field"
        from django.db.backends.util import truncate_name

        if f.db_index and not f.unique:
            qn = self.connection.ops.quote_name
            tablespace = f.db_tablespace or model._meta.db_tablespace
            if tablespace:
                sql = self.connection.ops.tablespace_sql(tablespace)
                if sql:
                    tablespace_sql = " " + sql
                else:
                    tablespace_sql = ""
            else:
                tablespace_sql = ""
            i_name = "%s_%s" % (model._meta.db_table, self._digest(f.column))
            output = [
                style.SQL_KEYWORD("CREATE INDEX")
                + " "
                + style.SQL_TABLE(qn(truncate_name(i_name, self.connection.ops.max_name_length())))
                + " "
                + style.SQL_KEYWORD("ON")
                + " "
                + style.SQL_TABLE(qn(model._meta.db_table))
                + " "
                + "(%s)" % style.SQL_FIELD(qn(f.column))
                + "%s;" % tablespace_sql
            ]
        else:
            output = []
        return output
Example #25
0
 def _create_index_name(self, model, column_names, suffix=""):
     """
     Generates a unique name for an index/unique constraint.
     """
     # If there is just one column in the index, use a default algorithm from Django
     if len(column_names) == 1 and not suffix:
         return truncate_name(
             '%s_%s' % (model._meta.db_table,
                        BaseDatabaseCreation._digest(column_names[0])),
             self.connection.ops.max_name_length())
     # Else generate the name for the index using a different algorithm
     table_name = model._meta.db_table.replace('"', '').replace('.', '_')
     index_unique_name = '_%x' % abs(
         hash((table_name, ','.join(column_names))))
     # If the index name is too long, truncate it
     index_name = (
         '%s_%s%s%s' %
         (table_name, column_names[0], index_unique_name, suffix)).replace(
             '"', '').replace('.', '_')
     if len(index_name) > self.connection.features.max_index_name_length:
         part = ('_%s%s%s' % (column_names[0], index_unique_name, suffix))
         index_name = '%s%s' % (table_name[:(
             self.connection.features.max_index_name_length - len(part))],
                                part)
     # It shouldn't start with an underscore (Oracle hates this)
     if index_name[0] == "_":
         index_name = index_name[1:]
     # If it's STILL too long, just hash it down
     if len(index_name) > self.connection.features.max_index_name_length:
         index_name = hashlib.md5(index_name).hexdigest(
         )[:self.connection.features.max_index_name_length]
     # It can't start with a number on Oracle, so prepend D if we need to
     if index_name[0].isdigit():
         index_name = "D%s" % index_name[:-1]
     return index_name
Example #26
0
 def _create_index_name(self, model, column_names, suffix=""):
     """
     Generates a unique name for an index/unique constraint.
     """
     # If there is just one column in the index, use a default algorithm from Django
     if len(column_names) == 1 and not suffix:
         return truncate_name(
             '%s_%s' % (model._meta.db_table, BaseDatabaseCreation._digest(column_names[0])),
             self.connection.ops.max_name_length()
         )
     # Else generate the name for the index using a different algorithm
     table_name = model._meta.db_table.replace('"', '').replace('.', '_')
     index_unique_name = '_%x' % abs(hash((table_name, ','.join(column_names))))
     # If the index name is too long, truncate it
     index_name = ('%s_%s%s%s' % (table_name, column_names[0], index_unique_name, suffix)).replace('"', '').replace('.', '_')
     if len(index_name) > self.connection.features.max_index_name_length:
         part = ('_%s%s%s' % (column_names[0], index_unique_name, suffix))
         index_name = '%s%s' % (table_name[:(self.connection.features.max_index_name_length - len(part))], part)
     # It shouldn't start with an underscore (Oracle hates this)
     if index_name[0] == "_":
         index_name = index_name[1:]
     # If it's STILL too long, just hash it down
     if len(index_name) > self.connection.features.max_index_name_length:
         index_name = hashlib.md5(index_name).hexdigest()[:self.connection.features.max_index_name_length]
     # It can't start with a number on Oracle, so prepend D if we need to
     if index_name[0].isdigit():
         index_name = "D%s" % index_name[:-1]
     return index_name
Example #27
0
    def _prepare(self, model):
        from django.db import connection
        from django.db.backends.util import truncate_name
        if self.order_with_respect_to:
            self.order_with_respect_to = self.get_field(self.order_with_respect_to)
            self.ordering = ('_order',)
        else:
            self.order_with_respect_to = None

        if self.pk is None:
            if self.parents:
                # Promote the first parent link in lieu of adding yet another
                # field.
                field = self.parents.value_for_index(0)
                field.primary_key = True
                self.pk = field
            else:
                auto = AutoField(verbose_name='ID', primary_key=True,
                        auto_created=True)
                model.add_to_class('id', auto)

        # If the db_table wasn't provided, use the app_label + module_name.
        if not self.db_table:
            self.db_table = "%s_%s" % (self.app_label, self.module_name)
            self.db_table = truncate_name(self.db_table, connection.ops.max_name_length())
Example #28
0
    def sql_for_pending_references(self, model, style, pending_references):
        "Returns any ALTER TABLE statements to add constraints after the fact."
        from django.db.backends.util import truncate_name

        if not model._meta.managed or model._meta.proxy:
            return []
        qn = self.connection.ops.quote_name
        final_output = []
        opts = model._meta
        if model in pending_references:
            for rel_class, f in pending_references[model]:
                rel_opts = rel_class._meta
                r_table = rel_opts.db_table
                r_col = f.column
                table = opts.db_table
                col = opts.get_field(f.rel.field_name).column
                # For MySQL, r_name must be unique in the first 64 characters.
                # So we are careful with character usage here.
                r_name = '%s_refs_%s_%s' % (r_col, col, self._digest(r_table, table))
                final_output.append(style.SQL_KEYWORD('ALTER TABLE') + ' %s ADD CONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s (%s)%s;' % \
                    (qn(r_table), qn(truncate_name(r_name, self.connection.ops.max_name_length())),
                    qn(r_col), qn(table), qn(col),
                    self.connection.ops.deferrable_sql()))
            del pending_references[model]
        return final_output
Example #29
0
    def _prepare(self, model):
        from django.db import connection
        from django.db.backends.util import truncate_name
        if self.order_with_respect_to:
            self.order_with_respect_to = self.get_field(
                self.order_with_respect_to)
            self.ordering = ('_order', )
        else:
            self.order_with_respect_to = None

        if self.pk is None:
            if self.parents:
                # Promote the first parent link in lieu of adding yet another
                # field.
                field = self.parents.value_for_index(0)
                field.primary_key = True
                self.setup_pk(field)
            else:
                auto = AutoField(verbose_name='ID',
                                 primary_key=True,
                                 auto_created=True)
                model.add_to_class('id', auto)

        # If the db_table wasn't provided, use the app_label + module_name.
        if not self.db_table:
            self.db_table = "%s_%s" % (self.app_label, self.module_name)
            self.db_table = truncate_name(self.db_table,
                                          connection.ops.max_name_length())
Example #30
0
    def sql_indexes_for_fields(self, model, fields, style):
        if len(fields) == 1 and fields[0].db_tablespace:
            tablespace_sql = self.connection.ops.tablespace_sql(fields[0].db_tablespace)
        elif model._meta.db_tablespace:
            tablespace_sql = self.connection.ops.tablespace_sql(model._meta.db_tablespace)
        else:
            tablespace_sql = ""
        if tablespace_sql:
            tablespace_sql = " " + tablespace_sql

        field_names = []
        qn = self.connection.ops.quote_name
        for f in fields:
            field_names.append(style.SQL_FIELD(qn(f.column)))

        index_name = "%s_%s" % (model._meta.db_table, self._digest([f.name for f in fields]))

        return [
            style.SQL_KEYWORD("CREATE INDEX") + " " +
            style.SQL_TABLE(qn(truncate_name(index_name, self.connection.ops.max_name_length()))) + " " +
            style.SQL_KEYWORD("ON") + " " +
            style.SQL_TABLE(qn(model._meta.db_table)) + " " +
            "(%s)" % style.SQL_FIELD(", ".join(field_names)) +
            "%s;" % tablespace_sql,
        ]
Example #31
0
    def sql_indexes_for_field(self, model, f, style):
        """
        Return the CREATE INDEX SQL statements for a single model field.
        """
        from django.db.backends.util import truncate_name

        if f.db_index and not f.unique and not f.rel and not f.primary_key:
            qn = self.connection.ops.quote_name
            tablespace = f.db_tablespace or model._meta.db_tablespace
            if tablespace:
                tablespace_sql = self.connection.ops.tablespace_sql(tablespace)
                if tablespace_sql:
                    tablespace_sql = ' ' + tablespace_sql
            else:
                tablespace_sql = ''
            i_name = '%s_%s' % (model._meta.db_table, self._digest(f.column))
            output = [style.SQL_KEYWORD('CREATE INDEX') + ' ' +
                style.SQL_TABLE(qn(truncate_name(
                    i_name, self.connection.ops.max_name_length()))) + ' ' +
                style.SQL_KEYWORD('ON') + ' ' +
                style.SQL_TABLE(qn(model._meta.db_table)) + ' ' +
                "(%s)" % style.SQL_FIELD(qn(f.column)) +
                "%s;" % tablespace_sql]
        else:
            output = []
        return output
Example #32
0
    def contribute_to_class(self, cls, name):
        from django.db import connection
        from django.db.backends.util import truncate_name

        cls._meta = self
        self.installed = re.sub('\.models$', '',
                                cls.__module__) in settings.INSTALLED_APPS
        # First, construct the default values for these options.
        self.object_name = cls.__name__
        self.module_name = self.object_name.lower()
        self.verbose_name = get_verbose_name(self.object_name)
        self.pk = CompositePrimaryKey()

        # Next, apply any overridden values from 'class Meta'.
        if self.meta:
            meta_attrs = self.meta.__dict__.copy()
            # We have to delay setup of this because self.fields isn't populated yet
            self._primary_key = meta_attrs.pop('primary_key', [])
            for name in self.meta.__dict__:
                # Ignore any private attributes that Django doesn't care about.
                # NOTE: We can't modify a dictionary's contents while looping
                # over it, so we loop over the *original* dictionary instead.
                if name.startswith('_'):
                    del meta_attrs[name]
            for attr_name in DEFAULT_NAMES:
                if attr_name in meta_attrs:
                    setattr(self, attr_name, meta_attrs.pop(attr_name))
                elif hasattr(self.meta, attr_name):
                    setattr(self, attr_name, getattr(self.meta, attr_name))

            # unique_together can be either a tuple of tuples, or a single
            # tuple of two strings. Normalize it to a tuple of tuples, so that
            # calling code can uniformly expect that.
            ut = meta_attrs.pop('unique_together',
                                getattr(self, 'unique_together'))
            if ut and not isinstance(ut[0], (tuple, list)):
                ut = (ut, )
            setattr(self, 'unique_together', ut)

            # verbose_name_plural is a special case because it uses a 's'
            # by default.
            setattr(
                self, 'verbose_name_plural',
                meta_attrs.pop('verbose_name_plural',
                               string_concat(self.verbose_name, 's')))

            # Any leftover attributes must be invalid.
            if meta_attrs != {}:
                raise TypeError, "'class Meta' got invalid attribute(s): %s" % ','.join(
                    meta_attrs.keys())
        else:
            self.verbose_name_plural = string_concat(self.verbose_name, 's')
        del self.meta

        # If the db_table wasn't provided, use the app_label + module_name.
        if not self.db_table:
            self.db_table = "%s_%s" % (self.app_label, self.module_name)
            self.db_table = truncate_name(self.db_table,
                                          connection.ops.max_name_length())
Example #33
0
    def contribute_to_class(self, cls, name):
        from django.db import connection
        from django.db.backends.util import truncate_name

        self.cls = cls
        cls._meta = self
        self.installed = re.sub('\.models$', '', cls.__module__) in settings.INSTALLED_APPS
        # First, construct the default values for these options.
        self.object_name = cls.__name__
        self.module_name = self.object_name.lower()
        self._verbose_name = CAMEL_CASE_RE.sub(' \\1', self.object_name).lower().strip()

        # Next, apply any overridden values from 'class Meta'.
        if self.meta:
            meta_attrs = self.meta.__dict__.copy()
            for name in self.meta.__dict__:
                # Ignore any private attributes that Django doesn't care about.
                # NOTE: We can't modify a dictionary's contents while looping
                # over it, so we loop over the *original* dictionary instead.
                if name.startswith('_'):
                    del meta_attrs[name]
            for attr_name in DEFAULT_NAMES:
                if attr_name in meta_attrs:
                    setattr(self, attr_name, meta_attrs.pop(attr_name))
                elif hasattr(self.meta, attr_name):
                    setattr(self, attr_name, getattr(self.meta, attr_name))

            for attr_name in DEPRECATED_NAMES:
                if attr_name in meta_attrs:
                    warnings.warn("%(cls)s: Meta.%(attr_name)s is deprecated. Use a "
                        "verbose_names() classmethod in the model "
                        "instead." % {'cls': cls, 'attr_name': attr_name},
                        PendingDeprecationWarning)
                    setattr(self, '_%s' % attr_name, meta_attrs.pop(attr_name))

            # unique_together can be either a tuple of tuples, or a single
            # tuple of two strings. Normalize it to a tuple of tuples, so that
            # calling code can uniformly expect that.
            ut = meta_attrs.pop('unique_together', self.unique_together)
            if ut and not isinstance(ut[0], (tuple, list)):
                ut = (ut,)
            self.unique_together = ut

            # verbose_name_plural is a special case because it uses a 's'
            # by default.
            if self._verbose_name_plural is None:
                self._verbose_name_plural = string_concat(self._verbose_name, 's')

            # Any leftover attributes must be invalid.
            if meta_attrs != {}:
                raise TypeError("'class Meta' got invalid attribute(s): %s" % ','.join(meta_attrs.keys()))
        else:
            self._verbose_name_plural = string_concat(self._verbose_name, 's')
        del self.meta

        # If the db_table wasn't provided, use the app_label + module_name.
        if not self.db_table:
            self.db_table = "%s_%s" % (self.app_label, self.module_name)
            self.db_table = truncate_name(self.db_table, connection.ops.max_name_length())
Example #34
0
 def quote_name(self, name):
     # SQL92 requires delimited (quoted) names to be case-sensitive.  When
     # not quoted, Oracle has case-insensitive behavior for identifiers, but
     # always defaults to uppercase.
     # We simplify things by making Oracle identifiers always uppercase.
     if not name.startswith('"') and not name.endswith('"'):
         name = '"%s"' % util.truncate_name(name.upper(), self.max_name_length())
     return name.upper()
Example #35
0
 def configure(self):
     data = self.configured_data
     if not data['INVITER_DB_TABLE']:
         # from: django/db/models/options.py#L112 (django 1.4)
         app, module = data['INVITER_CLASS'].lower().split('.')
         db_table_long = '{}_{}'.format(app, module)
         data['INVITER_DB_TABLE'] = truncate_name(
             db_table_long, connection.ops.max_name_length())
     return data
Example #36
0
    def sql_for_many_to_many_field(self, model, f, style):
        "Return the CREATE TABLE statements for a single m2m field"
        from django.db import models
        from django.db.backends.util import truncate_name

        output = []
        if f.creates_table:
            opts = model._meta
            qn = self.connection.ops.quote_name
            tablespace = f.db_tablespace or opts.db_tablespace
            if tablespace:
                sql = self.connection.ops.tablespace_sql(tablespace, inline=True)
                if sql:
                    tablespace_sql = ' ' + sql
                else:
                    tablespace_sql = ''
            else:
                tablespace_sql = ''
            table_output = [style.SQL_KEYWORD('CREATE TABLE') + ' ' + \
                style.SQL_TABLE(qn(f.m2m_db_table())) + ' (']
            table_output.append('    %s %s %s%s,' %
                (style.SQL_FIELD(qn('id')),
                style.SQL_COLTYPE(models.AutoField(primary_key=True).db_type()),
                style.SQL_KEYWORD('NOT NULL PRIMARY KEY'),
                tablespace_sql))

            deferred = []
            inline_output, deferred = self.sql_for_inline_many_to_many_references(model, f, style)
            table_output.extend(inline_output)

            table_output.append('    %s (%s, %s)%s' %
                (style.SQL_KEYWORD('UNIQUE'),
                style.SQL_FIELD(qn(f.m2m_column_name())),
                style.SQL_FIELD(qn(f.m2m_reverse_name())),
                tablespace_sql))
            table_output.append(')')
            if opts.db_tablespace:
                # f.db_tablespace is only for indices, so ignore its value here.
                table_output.append(self.connection.ops.tablespace_sql(opts.db_tablespace))
            table_output.append(';')
            output.append('\n'.join(table_output))

            for r_table, r_col, table, col in deferred:
                r_name = '%s_refs_%s_%x' % (r_col, col,
                        abs(hash((r_table, table))))
                output.append(style.SQL_KEYWORD('ALTER TABLE') + ' %s ADD CONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s (%s)%s;' %
                (qn(r_table),
                qn(truncate_name(r_name, self.connection.ops.max_name_length())),
                qn(r_col), qn(table), qn(col),
                self.connection.ops.deferrable_sql()))

            # Add any extra SQL needed to support auto-incrementing PKs
            autoinc_sql = self.connection.ops.autoinc_sql(f.m2m_db_table(), 'id')
            if autoinc_sql:
                for stmt in autoinc_sql:
                    output.append(stmt)
        return output
Example #37
0
 def _get_m2m_db_table(self, opts):
     "Function that can be curried to provide the m2m table name for this relation"
     if self.rel.through is not None:
         return self.rel.through_model._meta.db_table
     elif self.db_table:
         return self.db_table
     else:
         return util.truncate_name('%s_%s' % (opts.db_table, self.name),
                                   connection.ops.max_name_length())
Example #38
0
 def _get_m2m_db_table(self, opts):
     "Function that can be curried to provide the m2m table name for this relation"
     if self.rel.through is not None:
         return self.rel.through_model._meta.db_table
     elif self.db_table:
         return self.db_table
     else:
         return util.truncate_name('%s_%s' % (opts.db_table, self.name),
                                   connection.ops.max_name_length())
Example #39
0
 def configure(self):
     data = self.configured_data
     if not data['INVITER_DB_TABLE']:
         # from: django/db/models/options.py#L112 (django 1.4)
         app, module = data['INVITER_CLASS'].lower().split('.')
         db_table_long = '{}_{}'.format(app, module)
         data['INVITER_DB_TABLE'] = truncate_name(
                 db_table_long, connection.ops.max_name_length())
     return data
    def get_default_index_name(self, table_name, field):
        assert field.unique or field.db_index

        if field.unique:
            index_name = '%s_%s_key' % (table_name, field.column)
        elif field.db_index:
            index_name = '%s_%s' % (table_name, field.column)

        return truncate_name(index_name, self.connection.ops.max_name_length())
Example #41
0
 def quote_name(self, name):
     # SQL92 requires delimited (quoted) names to be case-sensitive.  When
     # not quoted, Oracle has case-insensitive behavior for identifiers, but
     # always defaults to uppercase.
     # We simplify things by making Oracle identifiers always uppercase.
     if not name.startswith('"') and not name.endswith('"'):
         name = '"%s"' % util.truncate_name(name.upper(),
                                            self.max_name_length())
     return name.upper()
Example #42
0
    def quote_name(self, name, upper=True, column = False, check_m2m = True):
        if not column:
            if check_m2m:
                name = self.check_m2m(name)
            if self.check_meta(name): #replication of Django flow for models where Meta.db_table is set by user
                name = name.upper()
        tn = truncate_name(name, connection.ops.max_name_length())

        return upper and tn.upper() or tn.lower()
Example #43
0
    def quote_name(self, name, upper=True, column = False, check_m2m = True):
        if not column:
            if check_m2m:
                name = self.check_m2m(name)
            if self.check_meta(name): #replication of Django flow for models where Meta.db_table is set by user
                name = name.upper()
        tn = truncate_name(name, connection.ops.max_name_length())

        return upper and tn.upper() or tn.lower()
Example #44
0
    def sql_for_many_to_many_field(self, model, f, style):
        "Return the CREATE TABLE statements for a single m2m field"
        from django.db import models
        from django.db.backends.util import truncate_name

        output = []
        if f.creates_table:
            opts = model._meta
            qn = self.connection.ops.quote_name
            tablespace = f.db_tablespace or opts.db_tablespace
            if tablespace:
                sql = self.connection.ops.tablespace_sql(tablespace, inline=True)
                if sql:
                    tablespace_sql = ' ' + sql
                else:
                    tablespace_sql = ''
            else:
                tablespace_sql = ''
            table_output = [style.SQL_KEYWORD('CREATE TABLE') + ' ' + \
                style.SQL_TABLE(qn(f.m2m_db_table())) + ' (']
            table_output.append('    %s %s %s%s,' %
                (style.SQL_FIELD(qn('id')),
                style.SQL_COLTYPE(models.AutoField(primary_key=True).db_type()),
                style.SQL_KEYWORD('NOT NULL PRIMARY KEY'),
                tablespace_sql))

            deferred = []
            inline_output, deferred = self.sql_for_inline_many_to_many_references(model, f, style)
            table_output.extend(inline_output)

            table_output.append('    %s (%s, %s)%s' %
                (style.SQL_KEYWORD('UNIQUE'),
                style.SQL_FIELD(qn(f.m2m_column_name())),
                style.SQL_FIELD(qn(f.m2m_reverse_name())),
                tablespace_sql))
            table_output.append(')')
            if opts.db_tablespace:
                # f.db_tablespace is only for indices, so ignore its value here.
                table_output.append(self.connection.ops.tablespace_sql(opts.db_tablespace))
            table_output.append(';')
            output.append('\n'.join(table_output))

            for r_table, r_col, table, col in deferred:
                r_name = '%s_refs_%s_%x' % (r_col, col,
                        abs(hash((r_table, table))))
                output.append(style.SQL_KEYWORD('ALTER TABLE') + ' %s ADD CONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s (%s)%s;' %
                (qn(r_table),
                truncate_name(r_name, self.connection.ops.max_name_length()),
                qn(r_col), qn(table), qn(col),
                self.connection.ops.deferrable_sql()))

            # Add any extra SQL needed to support auto-incrementing PKs
            autoinc_sql = self.connection.ops.autoinc_sql(f.m2m_db_table(), 'id')
            if autoinc_sql:
                for stmt in autoinc_sql:
                    output.append(stmt)
        return output
Example #45
0
 def foreign_key_sql(self, from_table_name, from_column_name, to_table_name, to_column_name):
     """
     Generates a full SQL statement to add a foreign key constraint
     """
     constraint_name = '%s_refs_%s_%x' % (from_column_name, to_column_name, abs(hash((from_table_name, to_table_name))))
     return 'ALTER TABLE %s ADD CONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s (%s)%s;' % (
         self.quote_name(from_table_name),
         self.quote_name(truncate_name(constraint_name, self._get_connection().ops.max_name_length())),
         self.quote_name(from_column_name),
         self.quote_name(to_table_name),
         self.quote_name(to_column_name),
         self._get_connection().ops.deferrable_sql() # Django knows this
     )
Example #46
0
    def _geom_index(self, style, db_table):
        "Creates an Oracle Geometry index (R-tree) for this geometry field."

        # Getting the index name, Oracle doesn't allow object
        # names > 30 characters.
        idx_name = truncate_name('%s_%s_id' % (db_table, self.column), 30)

        sql = (style.SQL_KEYWORD('CREATE INDEX ') +
               style.SQL_TABLE(qn(idx_name)) + style.SQL_KEYWORD(' ON ') +
               style.SQL_TABLE(qn(db_table)) + '(' +
               style.SQL_FIELD(qn(self.column)) + ') ' +
               style.SQL_KEYWORD('INDEXTYPE IS ') +
               style.SQL_TABLE('MDSYS.SPATIAL_INDEX') + ';')
        return sql
Example #47
0
    def makeAutoCreateIndexName(cls, column):
        """Syncdbで自動的に作られるインデクス名を偽造.
        """
        if BaseModel._style is None:
            from django.core.management.color import no_style
            BaseModel._style = no_style()

        from django.db import connections
        connection = connections[settings.DB_DEFAULT]
        qn = connection.ops.quote_name
        index_name = '%s_%s' % (cls.get_tablename(),
                                ('%x' % (abs(hash((column, ))) % 4294967296L)))
        return BaseModel._style.SQL_TABLE(
            qn(truncate_name(index_name, connection.ops.max_name_length())))
Example #48
0
    def alterFieldDataTypeByRemaking(self, model, old_field, new_field,
                                     strict):
        tmp_new_field = copy.deepcopy(new_field)
        tmp_new_field.column = truncate_name(
            "%s%s" % (self.psudo_column_prefix, tmp_new_field.column),
            self.connection.ops.max_name_length())
        self.add_field(model, tmp_new_field)

        #Transfer data from old field to new tmp field
        self.execute("UPDATE %s set %s=%s" % (self.quote_name(
            model._meta.db_table), self.quote_name(
                tmp_new_field.column), self.quote_name(old_field.column)))
        self.remove_field(model, old_field)
        return tmp_new_field, new_field
Example #49
0
    def create_index_name(self, table_name, column_names, suffix=""):
        """
        Generate a unique name for the index

        Django's logic for naming field indexes is different in the
        postgresql_psycopg2 backend, so we follow that for single-column
        indexes.
        """

        if len(column_names) == 1:
            return truncate_name(
                '%s_%s%s' % (table_name, column_names[0], suffix),
                self._get_connection().ops.max_name_length()
            )
        return super(DatabaseOperations, self).create_index_name(table_name, column_names, suffix)
Example #50
0
def sql_for_pending_references(self, model, style, pending_references):
    """
    Returns any ALTER TABLE statements to add constraints after the fact.
    """
    from django.db.backends.util import truncate_name
    opts = model._meta
    if not opts.managed or opts.swapped:
        return []
    qn = self.connection.ops.quote_name
    final_output = []
    if model in pending_references:
        for rel_class, f in pending_references[model]:
            rel_opts = rel_class._meta
            r_table = rel_opts.db_table
            r_col = f.column
            table = opts.db_table
            col = opts.get_field(f.rel.field_name).column

            if not hasattr(col, "columns"):
                # For MySQL, r_name must be unique in the first 64 characters.
                # So we are careful with character usage here.
                r_name = '%s_refs_%s_%s' % (r_col, col,
                                            self._digest(r_table, table))
                final_output.append(
                    style.SQL_KEYWORD('ALTER TABLE') +
                    ' %s ADD CONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s (%s)%s;'
                    % (qn(r_table),
                       qn(
                           truncate_name(
                               r_name, self.connection.ops.max_name_length())),
                       qn(r_col), qn(table), qn(col),
                       self.connection.ops.deferrable_sql()))
            else:
                try:
                    r_col = "_".join(cf.column for cf in f.fields)
                    col = "_".join(cf.column for cf in opts.pk.fields)
                    r_name = '%s_refs_%s_%s' % (r_col, col,
                                                self._digest(r_table, table))
                    final_output.append(style.SQL_KEYWORD('ALTER TABLE') + ' %s ADD CONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s (%s)%s;' %\
                                                                           (qn(r_table), qn(truncate_name(r_name, self.connection.ops.max_name_length())),
                                                                            ", ".join([style.SQL_FIELD(qn(cf.column)) for cf in f.fields]),
                                                                            qn(table),
                                                                            ", ".join([style.SQL_FIELD(qn(cf.column)) for cf in opts.pk.fields]),
                                                                            self.connection.ops.deferrable_sql()))
                except:
                    print "Skip constraint: TODO", rel_class, model
        del pending_references[model]
    return final_output
Example #51
0
    def rename_table(self, model, old_db_tablename, db_tablename):
        if old_db_tablename == db_tablename:
            # No Operation
            return []

        style = color.no_style()
        qn = self.connection.ops.quote_name
        max_name_length = self.connection.ops.max_name_length()
        creation = self.connection.creation

        sql = []
        refs = {}
        models = []

        for field in model._meta.local_many_to_many:
            if (field.rel and field.rel.through
                    and field.rel.through._meta.db_table == old_db_tablename):

                through = field.rel.through

                for m2m_field in through._meta.local_fields:
                    if m2m_field.rel and m2m_field.rel.to == model:
                        models.append(m2m_field.rel.to)
                        refs.setdefault(m2m_field.rel.to, []).append(
                            (through, m2m_field))

        remove_refs = refs.copy()

        for relto in models:
            sql.extend(
                creation.sql_remove_table_constraints(relto, remove_refs,
                                                      style))
        params = (qn(old_db_tablename), qn(db_tablename))
        sql.append('ALTER TABLE %s RENAME TO %s;' % params)

        for relto in models:
            for rel_class, f in refs[relto]:
                if rel_class._meta.db_table == old_db_tablename:
                    rel_class._meta.db_table = db_tablename

                rel_class._meta.db_table = \
                    truncate_name(rel_class._meta.db_table, max_name_length)

            sql.extend(creation.sql_for_pending_references(relto, style, refs))

        return sql
Example #52
0
    def __add_psudokey_column(self, style, cursor, table_name, pk_name,
                              column_list):
        qn = self.connection.ops.quote_name
        max_name_length = self.connection.ops.max_name_length()

        sql = style.SQL_KEYWORD( 'ALTER TABLE ' ) + \
            style.SQL_TABLE( qn( table_name ) ) + \
            style.SQL_KEYWORD( ' ADD COLUMN ' ) + \
            style.SQL_FIELD( qn( truncate_name( "%s%s" % ( self.psudo_column_prefix, "_".join( column_list ) ), max_name_length ) ) ) + \
            style.SQL_KEYWORD( ' GENERATED ALWAYS AS( CASE WHEN ' ) + \
            style.SQL_FIELD( "%s %s" % ( " IS NULL OR ".join( column_list ), 'IS NULL THEN ' ) ) + \
            style.SQL_FIELD( qn( pk_name ) ) + \
            style.SQL_KEYWORD( ' END ) ;' )
        cursor.execute('SET INTEGRITY FOR ' + style.SQL_TABLE(qn(table_name)) +
                       ' OFF CASCADE DEFERRED;')
        cursor.execute(sql)
        cursor.execute('SET INTEGRITY FOR ' + style.SQL_TABLE(table_name) +
                       ' IMMEDIATE CHECKED;')
        cursor.close()
    def sql_indexes_for_field(self, model, f, style):
        "Return any spatial index creation SQL for the field."
        from django.contrib.gis.db.models.fields import GeometryField

        output = super(OracleCreation,
                       self).sql_indexes_for_field(model, f, style)

        if isinstance(f, GeometryField):
            gqn = self.connection.ops.geo_quote_name
            qn = self.connection.ops.quote_name
            db_table = model._meta.db_table

            output.append(
                style.SQL_KEYWORD('INSERT INTO ') +
                style.SQL_TABLE('USER_SDO_GEOM_METADATA') +
                ' (%s, %s, %s, %s)\n  ' %
                tuple(map(qn, ['TABLE_NAME', 'COLUMN_NAME', 'DIMINFO', 'SRID'])
                      ) + style.SQL_KEYWORD(' VALUES ') + '(\n    ' +
                style.SQL_TABLE(gqn(db_table)) + ',\n    ' +
                style.SQL_FIELD(gqn(f.column)) + ',\n    ' +
                style.SQL_KEYWORD("MDSYS.SDO_DIM_ARRAY") + '(\n      ' +
                style.SQL_KEYWORD("MDSYS.SDO_DIM_ELEMENT") +
                ("('LONG', %s, %s, %s),\n      " %
                 (f._extent[0], f._extent[2], f._tolerance)) +
                style.SQL_KEYWORD("MDSYS.SDO_DIM_ELEMENT") +
                ("('LAT', %s, %s, %s)\n    ),\n" %
                 (f._extent[1], f._extent[3], f._tolerance)) +
                '    %s\n  );' % f.srid)

            if f.spatial_index:
                # Getting the index name, Oracle doesn't allow object
                # names > 30 characters.
                idx_name = truncate_name('%s_%s_id' % (db_table, f.column), 30)

                output.append(
                    style.SQL_KEYWORD('CREATE INDEX ') +
                    style.SQL_TABLE(qn(idx_name)) + style.SQL_KEYWORD(' ON ') +
                    style.SQL_TABLE(qn(db_table)) + '(' +
                    style.SQL_FIELD(qn(f.column)) + ') ' +
                    style.SQL_KEYWORD('INDEXTYPE IS ') +
                    style.SQL_TABLE('MDSYS.SPATIAL_INDEX') + ';')
        return output
Example #54
0
    def _prepare(self, model):
        from django.db import connection
        from django.db.backends.util import truncate_name
        if self.order_with_respect_to:
            self.order_with_respect_to = self.get_field(
                self.order_with_respect_to)
            self.ordering = ('_order', )
        else:
            self.order_with_respect_to = None

        if self.pk is None:
            auto = AutoField(verbose_name='ID', primary_key=True)
            auto.creation_counter = -1
            model.add_to_class('id', auto)

        # If the db_table wasn't provided, use the app_label + module_name.
        if not self.db_table:
            self.db_table = "%s_%s" % (self.app_label, self.module_name)
            self.db_table = truncate_name(self.db_table,
                                          connection.ops.max_name_length())
Example #55
0
    def change_unique(self, model, field_name, new_unique_value, initial=None):
        qn = self.connection.ops.quote_name
        opts = model._meta
        f = opts.get_field(field_name)
        constraint_name = truncate_name(
            '%s_%s_key' % (opts.db_table, f.column),
            self.connection.ops.max_name_length())

        if new_unique_value:
            params = (
                qn(opts.db_table),
                constraint_name,
                qn(f.column),
            )
            return ['ALTER TABLE %s ADD CONSTRAINT %s UNIQUE(%s);' % params]
        else:
            params = (
                qn(opts.db_table),
                constraint_name,
            )
            return ['ALTER TABLE %s DROP CONSTRAINT %s;' % params]
Example #56
0
 def sql_indexes_for_field(self, connection, model, f, style):
     # create GIST index for hstore column
     qn = connection.ops.quote_name
     index_name = '%s_%s_gist' % (model._meta.db_table, f.column)
     clauses = [
         style.SQL_KEYWORD('CREATE INDEX'),
         style.SQL_TABLE(
             qn(truncate_name(index_name,
                              connection.ops.max_name_length()))),
         style.SQL_KEYWORD('ON'),
         style.SQL_TABLE(qn(model._meta.db_table)),
         style.SQL_KEYWORD('USING GIST'),
         '(%s)' % style.SQL_FIELD(qn(f.column))
     ]
     # add tablespace clause
     tablespace = f.db_tablespace or model._meta.db_tablespace
     if tablespace:
         sql = connection.ops.tablespace_sql(tablespace)
         if sql:
             clauses.append(sql)
     clauses.append(';')
     return [' '.join(clauses)]
Example #57
0
def deferred_class_factory(model, attrs):
    """
    Returns a class object that is a copy of "model" with the specified "attrs"
    being replaced with DeferredAttribute objects. The "pk_value" ties the
    deferred attributes to a particular instance of the model.
    """
    class Meta:
        proxy = True
        app_label = model._meta.app_label

    # The app_cache wants a unique name for each model, otherwise the new class
    # won't be created (we get an old one back). Therefore, we generate the
    # name using the passed in attrs. It's OK to reuse an existing class
    # object if the attrs are identical.
    name = "%s_Deferred_%s" % (model.__name__, '_'.join(sorted(list(attrs))))
    name = util.truncate_name(name, 80, 32)

    overrides = dict((attr, DeferredAttribute(attr, model)) for attr in attrs)
    overrides["Meta"] = Meta
    overrides["__module__"] = model.__module__
    overrides["_deferred"] = True
    return type(str(name), (model, ), overrides)
Example #58
0
 def shorten_name(self, name):
     return truncate_name(name, self._get_connection().ops.max_name_length())