コード例 #1
0
ファイル: operations.py プロジェクト: anbz/django
 def sequence_reset_sql(self, style, model_list):
     from django.db import models
     output = []
     query = self._sequence_reset_sql
     for model in model_list:
         for f in model._meta.local_fields:
             if isinstance(f, models.AutoField):
                 no_autofield_sequence_name = self._get_no_autofield_sequence_name(model._meta.db_table)
                 table = self.quote_name(model._meta.db_table)
                 column = self.quote_name(f.column)
                 output.append(query % {
                     'no_autofield_sequence_name': no_autofield_sequence_name,
                     'table': table,
                     'column': column,
                     'table_name': strip_quotes(table),
                     'column_name': strip_quotes(column),
                 })
                 # Only one AutoField is allowed per model, so don't
                 # continue to loop
                 break
         for f in model._meta.many_to_many:
             if not f.remote_field.through:
                 no_autofield_sequence_name = self._get_no_autofield_sequence_name(f.m2m_db_table())
                 table = self.quote_name(f.m2m_db_table())
                 column = self.quote_name('id')
                 output.append(query % {
                     'no_autofield_sequence_name': no_autofield_sequence_name,
                     'table': table,
                     'column': column,
                     'table_name': strip_quotes(table),
                     'column_name': 'ID',
                 })
     return output
コード例 #2
0
ファイル: operations.py プロジェクト: anbz/django
 def sequence_reset_by_name_sql(self, style, sequences):
     sql = []
     for sequence_info in sequences:
         no_autofield_sequence_name = self._get_no_autofield_sequence_name(sequence_info['table'])
         table = self.quote_name(sequence_info['table'])
         column = self.quote_name(sequence_info['column'] or 'id')
         query = self._sequence_reset_sql % {
             'no_autofield_sequence_name': no_autofield_sequence_name,
             'table': table,
             'column': column,
             'table_name': strip_quotes(table),
             'column_name': strip_quotes(column),
         }
         sql.append(query)
     return sql
コード例 #3
0
ファイル: operations.py プロジェクト: anbz/django
 def _get_no_autofield_sequence_name(self, table):
     """
     Manually created sequence name to keep backward compatibility for
     AutoFields that aren't Oracle identity columns.
     """
     name_length = self.max_name_length() - 3
     return '%s_SQ' % truncate_name(strip_quotes(table), name_length).upper()
コード例 #4
0
ファイル: schema.py プロジェクト: savoirfairelinux/django
    def _create_index_name(self, model, column_names, suffix=""):
        """
        Generates 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 = strip_quotes(model._meta.db_table)
        hash_data = [table_name] + list(column_names)
        hash_suffix_part = "%s%s" % (self._digest(*hash_data), 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
ファイル: schema.py プロジェクト: ayanmadaan/ecomm
 def _alter_column_type_sql(self, model, old_field, new_field, new_type):
     self.sql_alter_column_type = 'ALTER COLUMN %(column)s TYPE %(type)s'
     # Cast when data type changed.
     if self._field_data_type(old_field) != self._field_data_type(
             new_field):
         self.sql_alter_column_type += ' USING %(column)s::%(type)s'
     # Make ALTER TYPE with SERIAL make sense.
     table = strip_quotes(model._meta.db_table)
     serial_fields_map = {
         'bigserial': 'bigint',
         'serial': 'integer',
         'smallserial': 'smallint'
     }
     if new_type.lower() in serial_fields_map:
         column = strip_quotes(new_field.column)
         sequence_name = "%s_%s_seq" % (table, column)
         return (
             (
                 self.sql_alter_column_type % {
                     "column": self.quote_name(column),
                     "type": serial_fields_map[new_type.lower()],
                 },
                 [],
             ),
             [
                 (
                     self.sql_delete_sequence % {
                         "sequence": self.quote_name(sequence_name),
                     },
                     [],
                 ),
                 (
                     self.sql_create_sequence % {
                         "sequence": self.quote_name(sequence_name),
                     },
                     [],
                 ),
                 (
                     self.sql_alter_column % {
                         "table": self.quote_name(table),
                         "changes": self.sql_alter_column_default % {
                             "column":
                             self.quote_name(column),
                             "default":
                             "nextval('%s')" %
                             self.quote_name(sequence_name),
                         }
                     },
                     [],
                 ),
                 (
                     self.sql_set_sequence_max % {
                         "table": self.quote_name(table),
                         "column": self.quote_name(column),
                         "sequence": self.quote_name(sequence_name),
                     },
                     [],
                 ),
                 (
                     self.sql_set_sequence_owner % {
                         'table': self.quote_name(table),
                         'column': self.quote_name(column),
                         'sequence': self.quote_name(sequence_name),
                     },
                     [],
                 ),
             ],
         )
     else:
         return super()._alter_column_type_sql(model, old_field, new_field,
                                               new_type)
コード例 #6
0
ファイル: operations.py プロジェクト: anbz/django
 def last_insert_id(self, cursor, table_name, pk_name):
     sq_name = self._get_sequence_name(cursor, strip_quotes(table_name), pk_name)
     cursor.execute('"%s".currval' % sq_name)
     return cursor.fetchone()[0]
コード例 #7
0
ファイル: operations.py プロジェクト: JBKahn/django
 def _get_trigger_name(self, table):
     name_length = self.max_name_length() - 3
     trigger_name = '%s_TR' % strip_quotes(table)
     return truncate_name(trigger_name, name_length).upper()
コード例 #8
0
ファイル: operations.py プロジェクト: JBKahn/django
 def _get_sequence_name(self, table):
     name_length = self.max_name_length() - 3
     sequence_name = '%s_SQ' % strip_quotes(table)
     return truncate_name(sequence_name, name_length).upper()
コード例 #9
0
 def _create_spatial_index_name(self, model, field):
     # Oracle doesn't allow object names > 30 characters. Use this scheme
     # instead of self._create_index_name() for backwards compatibility.
     return truncate_name('%s_%s_id' % (strip_quotes(model._meta.db_table), field.column), 30)
コード例 #10
0
 def _alter_column_type_sql(self, model, old_field, new_field, new_type):
     self.sql_alter_column_type = "ALTER COLUMN %(column)s TYPE %(type)s"
     # Cast when data type changed.
     using_sql = " USING %(column)s::%(type)s"
     new_internal_type = new_field.get_internal_type()
     old_internal_type = old_field.get_internal_type()
     if new_internal_type == "ArrayField" and new_internal_type == old_internal_type:
         # Compare base data types for array fields.
         if list(self._field_base_data_types(old_field)) != list(
             self._field_base_data_types(new_field)
         ):
             self.sql_alter_column_type += using_sql
     elif self._field_data_type(old_field) != self._field_data_type(new_field):
         self.sql_alter_column_type += using_sql
     # Make ALTER TYPE with IDENTITY make sense.
     table = strip_quotes(model._meta.db_table)
     auto_field_types = {
         "AutoField",
         "BigAutoField",
         "SmallAutoField",
     }
     old_is_auto = old_internal_type in auto_field_types
     new_is_auto = new_internal_type in auto_field_types
     if new_is_auto and not old_is_auto:
         column = strip_quotes(new_field.column)
         return (
             (
                 self.sql_alter_column_type
                 % {
                     "column": self.quote_name(column),
                     "type": new_type,
                 },
                 [],
             ),
             [
                 (
                     self.sql_add_identity
                     % {
                         "table": self.quote_name(table),
                         "column": self.quote_name(column),
                     },
                     [],
                 ),
             ],
         )
     elif old_is_auto and not new_is_auto:
         # Drop IDENTITY if exists (pre-Django 4.1 serial columns don't have
         # it).
         self.execute(
             self.sql_drop_indentity
             % {
                 "table": self.quote_name(table),
                 "column": self.quote_name(strip_quotes(old_field.column)),
             }
         )
         column = strip_quotes(new_field.column)
         sequence_name = "%s_%s_seq" % (table, column)
         fragment, _ = super()._alter_column_type_sql(
             model, old_field, new_field, new_type
         )
         return fragment, [
             (
                 # Drop the sequence if exists (Django 4.1+ identity columns
                 # don't have it).
                 self.sql_delete_sequence
                 % {
                     "sequence": self.quote_name(sequence_name),
                 },
                 [],
             ),
         ]
     else:
         return super()._alter_column_type_sql(model, old_field, new_field, new_type)
コード例 #11
0
ファイル: creation.py プロジェクト: bengkui2015/hello-world
 def _database_exists(self, cursor, database_name):
     cursor.execute('SELECT 1 FROM pg_catalog.pg_database WHERE datname = %s', [strip_quotes(database_name)])
     return cursor.fetchone() is not None
コード例 #12
0
 def last_insert_id(self, cursor, table_name, pk_name):
     sq_name = self._get_sequence_name(cursor, strip_quotes(table_name),
                                       pk_name)
     cursor.execute('"%s".currval' % sq_name)
     return cursor.fetchone()[0]
コード例 #13
0
 def _get_trigger_name(self, table):
     name_length = self.max_name_length() - 3
     trigger_name = '%s_TR' % strip_quotes(table)
     return truncate_name(trigger_name, name_length).upper()
コード例 #14
0
ファイル: creation.py プロジェクト: sinodotahope/typeidea-env
 def _database_exists(self, cursor, database_name):
     cursor.execute('SELECT 1 FROM pg_catalog.pg_database WHERE datname = %s', [strip_quotes(database_name)])
     return cursor.fetchone() is not None
コード例 #15
0
    def _remake_table(self, model, create_field=None, delete_field=None, alter_field=None):
        """
        Shortcut to transform a model from old_model into new_model

        This follows the correct procedure to perform non-rename or column
        addition operations based on SQLite's documentation

        https://www.sqlite.org/lang_altertable.html#caution

        The essential steps are:
          1. Create a table with the updated definition called "new__app_model"
          2. Copy the data from the existing "app_model" table to the new table
          3. Drop the "app_model" table
          4. Rename the "new__app_model" table to "app_model"
          5. Restore any index of the previous "app_model" table.
        """
        # Self-referential fields must be recreated rather than copied from
        # the old model to ensure their remote_field.field_name doesn't refer
        # to an altered field.
        def is_self_referential(f):
            return f.is_relation and f.remote_field.model is model
        # Work out the new fields dict / mapping
        body = {
            f.name: f.clone() if is_self_referential(f) else f
            for f in model._meta.local_concrete_fields
        }
        # Since mapping might mix column names and default values,
        # its values must be already quoted.
        mapping = {f.column: self.quote_name(
            f.column) for f in model._meta.local_concrete_fields}
        # This maps field names (not columns) for things like unique_together
        rename_mapping = {}
        # If any of the new or altered fields is introducing a new PK,
        # remove the old one
        restore_pk_field = None
        if getattr(create_field, 'primary_key', False) or (
                alter_field and getattr(alter_field[1], 'primary_key', False)):
            for name, field in list(body.items()):
                if field.primary_key:
                    field.primary_key = False
                    restore_pk_field = field
                    if field.auto_created:
                        del body[name]
                        del mapping[field.column]
        # Add in any created fields
        if create_field:
            body[create_field.name] = create_field
            # Choose a default and insert it into the copy map
            if not create_field.many_to_many and create_field.concrete:
                mapping[create_field.column] = self.quote_value(
                    self.effective_default(create_field)
                )
        # Add in any altered fields
        if alter_field:
            old_field, new_field = alter_field
            body.pop(old_field.name, None)
            mapping.pop(old_field.column, None)
            body[new_field.name] = new_field
            if old_field.null and not new_field.null:
                case_sql = "coalesce(%(col)s, %(default)s)" % {
                    'col': self.quote_name(old_field.column),
                    'default': self.quote_value(self.effective_default(new_field))
                }
                mapping[new_field.column] = case_sql
            else:
                mapping[new_field.column] = self.quote_name(old_field.column)
            rename_mapping[old_field.name] = new_field.name
        # Remove any deleted fields
        if delete_field:
            del body[delete_field.name]
            del mapping[delete_field.column]
            # Remove any implicit M2M tables
            if delete_field.many_to_many and delete_field.remote_field.through._meta.auto_created:
                return self.delete_model(delete_field.remote_field.through)
        # Work inside a new app registry
        apps = Apps()

        # Work out the new value of unique_together, taking renames into
        # account
        unique_together = [
            [rename_mapping.get(n, n) for n in unique]
            for unique in model._meta.unique_together
        ]

        # Work out the new value for index_together, taking renames into
        # account
        index_together = [
            [rename_mapping.get(n, n) for n in index]
            for index in model._meta.index_together
        ]

        indexes = model._meta.indexes
        if delete_field:
            indexes = [
                index for index in indexes
                if delete_field.name not in index.fields
            ]

        constraints = list(model._meta.constraints)

        # Provide isolated instances of the fields to the new model body so
        # that the existing model's internals aren't interfered with when
        # the dummy model is constructed.
        body_copy = copy.deepcopy(body)

        # Construct a new model with the new fields to allow self referential
        # primary key to resolve to. This model won't ever be materialized as a
        # table and solely exists for foreign key reference resolution purposes.
        # This wouldn't be required if the schema editor was operating on model
        # states instead of rendered models.
        meta_contents = {
            'app_label': model._meta.app_label,
            'db_table': model._meta.db_table,
            'unique_together': unique_together,
            'index_together': index_together,
            'indexes': indexes,
            'constraints': constraints,
            'apps': apps,
        }
        meta = type("Meta", (), meta_contents)
        body_copy['Meta'] = meta
        body_copy['__module__'] = model.__module__
        type(model._meta.object_name, model.__bases__, body_copy)

        # Construct a model with a renamed table name.
        body_copy = copy.deepcopy(body)
        meta_contents = {
            'app_label': model._meta.app_label,
            'db_table': 'new__%s' % strip_quotes(model._meta.db_table),
            'unique_together': unique_together,
            'index_together': index_together,
            'indexes': indexes,
            'constraints': constraints,
            'apps': apps,
        }
        meta = type("Meta", (), meta_contents)
        body_copy['Meta'] = meta
        body_copy['__module__'] = model.__module__
        new_model = type('New%s' % model._meta.object_name,
                         model.__bases__, body_copy)

        # Create a new table with the updated schema.
        self.create_model(new_model)

        # Copy data from the old table into the new table
        self.execute("INSERT INTO %s %s SELECT %s FROM %s" % (
            self.quote_name(new_model._meta.db_table),
            ', '.join(self.quote_name(x) for x in mapping),
            ', '.join(mapping.values()),
            self.quote_name(model._meta.db_table),
        ))

        # Delete the old table to make way for the new
        self.delete_model(model, handle_autom2m=False)

        # Rename the new table to take way for the old
        self.alter_db_table(
            new_model, new_model._meta.db_table, model._meta.db_table,
            disable_constraints=False,
        )

        # Run deferred SQL on correct table
        for sql in self.deferred_sql:
            self.execute(sql)
        self.deferred_sql = []
        # Fix any PK-removed field
        if restore_pk_field:
            restore_pk_field.primary_key = True
コード例 #16
0
def create_object_name(ops, obj, sufix=''):
    name_length = ops.max_name_length() - len(sufix)
    obj_name = utils.strip_quotes(obj)
    return utils.truncate_name(obj_name, name_length)
コード例 #17
0
 def _create_spatial_index_name(self, model, field):
     # Oracle doesn't allow object names > 30 characters. Use this scheme
     # instead of self._create_index_name() for backwards compatibility.
     return truncate_name(
         "%s_%s_id" % (strip_quotes(model._meta.db_table), field.column),
         30)
コード例 #18
0
 def _alter_column_type_sql(self, model, old_field, new_field, new_type):
     self.sql_alter_column_type = "ALTER COLUMN %(column)s TYPE %(type)s"
     # Cast when data type changed.
     using_sql = " USING %(column)s::%(type)s"
     new_internal_type = new_field.get_internal_type()
     old_internal_type = old_field.get_internal_type()
     if new_internal_type == "ArrayField" and new_internal_type == old_internal_type:
         # Compare base data types for array fields.
         if list(self._field_base_data_types(old_field)) != list(
                 self._field_base_data_types(new_field)):
             self.sql_alter_column_type += using_sql
     elif self._field_data_type(old_field) != self._field_data_type(
             new_field):
         self.sql_alter_column_type += using_sql
     # Make ALTER TYPE with SERIAL make sense.
     table = strip_quotes(model._meta.db_table)
     serial_fields_map = {
         "bigserial": "bigint",
         "serial": "integer",
         "smallserial": "smallint",
     }
     if new_type.lower() in serial_fields_map:
         column = strip_quotes(new_field.column)
         sequence_name = "%s_%s_seq" % (table, column)
         return (
             (
                 self.sql_alter_column_type % {
                     "column": self.quote_name(column),
                     "type": serial_fields_map[new_type.lower()],
                 },
                 [],
             ),
             [
                 (
                     self.sql_delete_sequence % {
                         "sequence": self.quote_name(sequence_name),
                     },
                     [],
                 ),
                 (
                     self.sql_create_sequence % {
                         "sequence": self.quote_name(sequence_name),
                     },
                     [],
                 ),
                 (
                     self.sql_alter_column % {
                         "table": self.quote_name(table),
                         "changes": self.sql_alter_column_default % {
                             "column":
                             self.quote_name(column),
                             "default":
                             "nextval('%s')" %
                             self.quote_name(sequence_name),
                         },
                     },
                     [],
                 ),
                 (
                     self.sql_set_sequence_max % {
                         "table": self.quote_name(table),
                         "column": self.quote_name(column),
                         "sequence": self.quote_name(sequence_name),
                     },
                     [],
                 ),
                 (
                     self.sql_set_sequence_owner % {
                         "table": self.quote_name(table),
                         "column": self.quote_name(column),
                         "sequence": self.quote_name(sequence_name),
                     },
                     [],
                 ),
             ],
         )
     else:
         return super()._alter_column_type_sql(model, old_field, new_field,
                                               new_type)
コード例 #19
0
 def _get_sequence_name(self, table):
     name_length = self.max_name_length() - 3
     sequence_name = '%s_SQ' % strip_quotes(table)
     return truncate_name(sequence_name, name_length).upper()
コード例 #20
0
 def _alter_column_type_sql(self, model, old_field, new_field, new_type):
     self.sql_alter_column_type = 'ALTER COLUMN %(column)s TYPE %(type)s'
     # Cast when data type changed.
     using_sql = ' USING %(column)s::%(type)s'
     new_internal_type = new_field.get_internal_type()
     old_internal_type = old_field.get_internal_type()
     if new_internal_type == 'ArrayField' and new_internal_type == old_internal_type:
         # Compare base data types for array fields.
         if list(self._field_base_data_types(old_field)) != list(
                 self._field_base_data_types(new_field)):
             self.sql_alter_column_type += using_sql
     elif self._field_data_type(old_field) != self._field_data_type(
             new_field):
         self.sql_alter_column_type += using_sql
     # Make ALTER TYPE with SERIAL make sense.
     table = strip_quotes(model._meta.db_table)
     serial_fields_map = {
         'bigserial': 'bigint',
         'serial': 'integer',
         'smallserial': 'smallint'
     }
     if new_type.lower() in serial_fields_map:
         column = strip_quotes(new_field.column)
         sequence_name = "%s_%s_seq" % (table, column)
         return (
             (
                 self.sql_alter_column_type % {
                     "column": self.quote_name(column),
                     "type": serial_fields_map[new_type.lower()],
                 },
                 [],
             ),
             [
                 (
                     self.sql_delete_sequence % {
                         "sequence": self.quote_name(sequence_name),
                     },
                     [],
                 ),
                 (
                     self.sql_create_sequence % {
                         "sequence": self.quote_name(sequence_name),
                     },
                     [],
                 ),
                 (
                     self.sql_alter_column % {
                         "table": self.quote_name(table),
                         "changes": self.sql_alter_column_default % {
                             "column":
                             self.quote_name(column),
                             "default":
                             "nextval('%s')" %
                             self.quote_name(sequence_name),
                         }
                     },
                     [],
                 ),
                 (
                     self.sql_set_sequence_max % {
                         "table": self.quote_name(table),
                         "column": self.quote_name(column),
                         "sequence": self.quote_name(sequence_name),
                     },
                     [],
                 ),
                 (
                     self.sql_set_sequence_owner % {
                         'table': self.quote_name(table),
                         'column': self.quote_name(column),
                         'sequence': self.quote_name(sequence_name),
                     },
                     [],
                 ),
             ],
         )
     elif old_field.db_parameters(
             connection=self.connection)['type'] in serial_fields_map:
         # Drop the sequence if migrating away from AutoField.
         column = strip_quotes(new_field.column)
         sequence_name = '%s_%s_seq' % (table, column)
         fragment, _ = super()._alter_column_type_sql(
             model, old_field, new_field, new_type)
         return fragment, [
             (
                 self.sql_delete_sequence % {
                     'sequence': self.quote_name(sequence_name),
                 },
                 [],
             ),
         ]
     else:
         return super()._alter_column_type_sql(model, old_field, new_field,
                                               new_type)