django_evolution.db.common

Common evolution operations backend for databases.

Classes

BaseEvolutionOperations(database_state[, ...])

Base class for evolution operations for a database backend.

class django_evolution.db.common.BaseEvolutionOperations(database_state, connection=<django.db.DefaultConnectionProxy object>)

Bases: object

Base class for evolution operations for a database backend.

name = None

The name of the database type.

New in version 2.3.

supported_change_attrs = {'db_column', 'db_index', 'db_table', 'decimal_places', 'max_digits', 'max_length', 'null', 'unique'}

A set of attributes that can be changed in the database.

supported_change_meta = {'constraints': True, 'db_table_comment': False, 'index_together': True, 'indexes': True, 'unique_together': True}
mergeable_ops = ('add_column', 'change_column', 'change_metadelete_column')
ignored_m2m_attrs = {<class 'django.db.models.fields.related.ManyToManyField'>: {'null'}}
default_tablespace = None

The default tablespace for the database, if tablespaces are supported.

New in version 2.2.

Type:

unicode

change_column_type_sets_attrs = True

Whether a column type change operation also sets new attributes.

If False, attributes will be set through the standard field change operation.

New in version 2.2.

Type:

bool

alter_table_sql_result_cls

alias of AlterTableSQLResult

__init__(database_state, connection=<django.db.DefaultConnectionProxy object>)

Initialize the evolution operations.

Parameters:
can_add_index(index)

Return whether an index can be added to this database.

This will determine if the database connection supports the state represented in the index well enough to be written to the database.

Note that not all features of an index are required. At the moment, to comply with Django’s logic (BaseDatabaseSchemaEditor.add_index()), an index can be written so long as it either does not contain expressions or the database backend supports expression indexes.

Parameters:

index (django.db.models.Index) – The index that would be written.

Returns:

True if the index can be written. False if it cannot.

Return type:

bool

get_field_type_allows_default(field)

Return whether default values are allowed for a field.

By default, default values are always allowed. Subclasses should override this if some types do not allow for defaults.

New in version 2.2.

Parameters:

field (django.db.models.Field) – The field to check.

Returns:

True if default values are allowed. False if they’re not.

Return type:

bool

get_deferrable_sql()

Return the SQL for marking a reference as deferrable.

New in version 2.2.

Returns:

The SQL for marking a reference as deferrable.

Return type:

unicode

get_change_column_type_sql(model, old_field, new_field)

Return SQL for changing a column type.

This should be limited to the ALTER TABLE or equivalent for changing the column. It should not affect constraints or other fields.

Subclasses must implement this, unless they override change_column_type().

New in version 2.2.

Parameters:
Returns:

The SQL statements for changing the column type.

Return type:

django_evolution.db.sql_result.SQLResult

build_column_schema(model, field, initial=None, skip_null_constraint=False, skip_primary_or_unique_constraint=False, skip_references=False)

Return information on the schema for building a column.

This is used when creating or re-creating columns on a table.

Parameters:
  • model (type) – The parent model of the column.

  • field (django.db.models.Field) – The field to build the column schema from.

  • initial (object or callable) – The initial data for the column.

  • skip_null_constraint (bool, optional) – Whether to skip adding NULL/NOT NULL constraints. This can be used to temporarily omit this part of the schema while adding the column.

  • skip_references (bool, optional) – Whether to skip adding REFERENCES ... information. This can be used to temporarily omit this part of the schema while adding the column, handling that step separately.

Returns:

The schema information. This has the following keys:

db_type (unicode):

The database-specific column type.

definition (list):

A list of parts of the column schema definition. Each of these is a keyword (which may or may not have spaces) or values used for constructing the column.

definition_sql_params (list):

The list of SQL parameters to pass to the executor. These will be safely handled by the database backend.

name (unicode):

The name of the column.

Return type:

dict

generate_table_ops_sql(mutator, ops)

Generates SQL for a sequence of mutation operations.

This will process each operation one-by-one, generating default SQL, using generate_table_op_sql().

generate_table_op_sql(mutator, op, prev_sql_result, prev_op)

Generates SQL for a single mutation operation.

This will call different SQL-generating functions provided by the class, depending on the details of the operation.

If two adjacent operations can be merged together (meaning that they can be turned into one ALTER TABLE statement), they’ll be placed in the same AlterTableSQLResult.

quote_sql_param(param)

Add protective quoting around an SQL string parameter

rename_column(model, old_field, new_field)

Renames the specified column.

This must be implemented by subclasses. It must return an SQLResult or AlterTableSQLResult representing the SQL needed to rename the column.

get_rename_table_sql(model, old_db_table, new_db_table)

Return SQL for renaming a table.

Parameters:
Returns:

The resulting SQL for renaming the table.

Return type:

django_evolution.db.sql_result.SQLResult

rename_table(model, old_db_table, new_db_table)

Rename a table.

This will take care of removing and then restoring any primary field constraints. If an evolver backend doesn’t support this, or has another method for managing these constraints, it should override this method.

Parameters:
Returns:

The resulting SQL for renaming the table.

Return type:

django_evolution.db.sql_result.SQLResult

delete_column(model, f)
delete_table(table_name)
add_m2m_table(model, field)

Return SQL statements for creating a ManyToManyField’s table.

Parameters:
Returns:

The list of SQL statements for creating the table.

Return type:

list

add_column(model, field, initial)

Add a column to a table.

Parameters:
  • model (type) – The model representing the table the column will be added to.

  • field (django.db.models.Field) – The field representing the column being added.

  • initial (object or callable) – The initial data to set for the column in all rows. If this is a callable, it will be called and the result will be used.

Returns:

The SQL for adding the column.

Return type:

django_evolution.db.sql_result.AlterTableSQLResult

set_field_null(model, field, null)
create_index(model, field)

Returns the SQL for creating an index for a single field.

The index will be recorded in the database signature for future operations within the transaction, and the appropriate SQL for creating the index will be returned.

This is not intended to be overridden.

create_unique_index(model, index_name, fields)
drop_index(model, field)

Returns the SQL for dropping an index for a single field.

The index matching the field’s column will be looked up and, if found, the SQL for dropping it will be returned.

If the index was not found on the database or in the database signature, this won’t return any SQL statements.

This is not intended to be overridden. Instead, subclasses should override get_drop_index_sql.

drop_index_by_name(model, index_name)

Returns the SQL to drop an index, given an index name.

The index will be removed fom the database signature, and the appropriate SQL for dropping the index will be returned.

This is not intended to be overridden. Instead, subclasses should override get_drop_index_sql.

get_drop_index_sql(model, index_name)

Returns the database-specific SQL to drop an index.

This can be overridden by subclasses if they use a syntax other than “DROP INDEX <name>;”

get_new_index_name(model, fields, unique=False)

Return a newly generated index name.

This returns a unique index name for any indexes created by django-evolution, based on how Django would compute the index.

Parameters:
Returns:

The generated name for the index.

Return type:

str

get_new_constraint_name(table_name, column)

Return a newly-generated constraint name.

Parameters:
  • table_name (unicode) – The name of the table.

  • column (unicode) – The name of the column.

Returns:

The new constraint name.

Return type:

unicode

get_default_index_name(table_name, field)

Return 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.

Parameters:
Returns:

The name of the index.

Return type:

str

get_default_index_together_name(table_name, fields)

Returns a default index name for an index_together.

This will return an index name for the given field that matches what Django uses for index_together fields.

Parameters:
Returns:

The name of the index.

Return type:

str

change_column_attrs(model, mutation, field_name, new_attrs)

Return the SQL for changing one or more column attributes.

This will generate all the statements needed for changing a set of attributes for a column.

The resulting AlterTableSQLResult contains all the SQL needed to apply these attributes.

Parameters:
  • model (type) – The model class that owns the field.

  • mutation (django_evolution.mutations.BaseModelMutation) – The mutation applying this change.

  • field_name (unicode) – The name of the field on the model.

  • new_attrs (dict) – A dictionary mapping attributes to new values.

Returns:

The SQL for modifying the column.

Return type:

django_evolution.db.sql_result.AlterTableSQLResult

change_column_attr_null(model, mutation, field, old_value, new_value)

Returns the SQL for changing a column’s NULL/NOT NULL attribute.

change_column_attr_decimal_type(model, mutation, field, new_max_digits, new_decimal_places)

Return SQL for changing a column’s max digits and decimal places.

This is used for DecimalField and subclasses to change the maximum number of digits or decimal places. As these are used together as a column type, they must be considered together as one attribute change.

Parameters:
  • model (type) – The model class that owns the field.

  • mutation (django_evolution.mutations.BaseModelMutation) – The mutation applying this change.

  • field (django.db.models.DecimalField) – The field being modified.

  • new_max_digits (int) – The new value for max_digits. If None, it wasn’t provided in the attribute change.

  • new_decimal_places (int) – The new value for decimal_places. If None, it wasn’t provided in the attribute change.

Returns:

The SQL for modifying the value.

Return type:

django_evolution.db.sql_result.AlterTableSQLResult

change_column_attr_max_length(model, mutation, field, old_value, new_value)

Returns the SQL for changing a column’s max length.

change_column_attr_db_column(model, mutation, field, old_value, new_value)

Returns the SQL for changing a column’s name.

change_column_attr_db_table(model, mutation, field, old_value, new_value)

Returns the SQL for changing the table for a ManyToManyField.

change_column_attrs_db_index_unique(model, mutation, field, old_db_index, new_db_index, old_unique, new_unique)

Return SQL for changing indexes due to db_index or unique.

This determines whether standard or unique indexes need to be dropped or added, and returns the resulting SQL.

Unique indexes are dropped if a field went from unique=True to unique=False.

If not dropping a unique index, but the field was set to db_index=True, unique=False, and either db_index=False or unique=True is being set, a stnadard index will be dropped.

Unique indexes are added if a field went from unique=False to unique=True.

If not adding a unique index, but the field was set to db_index=False or unique=True and is being set to db_index=True, unique=False, then a standard index will be added.

New in version 2.3.

Parameters:
  • model (django.db.models.Model) – The model being changed.

  • mutation (django_evolution.mutations.BaseModelMutation) – The mutation applying this change.

  • field (django.db.models.DecimalField) – The field being modified.

  • old_db_index (bool) – The old db_index value.

  • new_db_index (bool) – The new db_index value.

  • old_unique (bool) – The old unique value.

  • new_unique (bool) – The new unique value.

Returns:

The SQL for dropping and/or adding indexes.

Return type:

django_evolution.db.sql_result.AlterTableSQLResult

change_column_attr_db_index(model, mutation, field, old_value, new_value)

Return the SQL for creating/dropping indexes for a column.

If setting db_index=True, SQL for generating the index will be returned.

If setting db_index=False, SQL for dropping the index will be returned.

Creating or dropping the SQL will also modify the cached/queued database index state, used by other operations that work with indexes.

Subclasses should override this if they’re sensitive to the order in which SQL is generated or cached/queued database index state is modified.

Parameters:
  • model (django.db.models.Model) – The model being changed.

  • mutation (django_evolution.mutations.BaseModelMutation) – The mutation applying this change.

  • field (django.db.models.DecimalField) – The field being modified.

  • old_value (bool) – The old value for db_index.

  • new_value (bool) – The new value for db_index.

Returns:

The resulting SQL for creating the index or scheduling a drop.

Return type:

django_evolution.db.sql_result.SQLResult

change_column_attr_unique(model, mutation, field, old_value, new_value)

Returns the SQL to change a field’s unique flag.

Changing the unique flag for a given column will affect indexes. If setting unique to True, an index will be created in the database signature for future operations within the transaction. If False, the index will be dropped from the database signature.

The SQL needed to change the column will be returned.

This is not intended to be overridden. Instead, subclasses should override get_change_unique_sql.

change_column_type(model, old_field, new_field, new_attrs)

Return SQL to change the type of a column.

New in version 2.2.

Parameters:
Returns:

The SQL statements for changing the column type.

Return type:

django_evolution.sql_result.AlterTableSQLResult

get_change_unique_sql(model, field, new_unique_value, constraint_name, initial)

Returns the database-specific SQL to change a column’s unique flag.

This can be overridden by subclasses if they use a different syntax.

get_drop_unique_constraint_sql(model, index_name)
change_meta_unique_together(model, old_unique_together, new_unique_together)

Change the unique_together constraints of a table.

Parameters:
  • model (django.db.models.Model) – The model being changed.

  • old_unique_together (list) – The old value for unique_together.

  • new_unique_together (list) – The new value for unique_together.

Returns:

The SQL statements for changing the unique_together constraints.

Return type:

django_evolution.sql_result.SQLResult

change_meta_index_together(model, old_index_together, new_index_together)

Change the index_together indexes of a table.

Parameters:
  • model (django.db.models.Model) – The model being changed.

  • old_index_together (list) – The old value for index_together.

  • new_index_together (list) – The new value for index_together.

Returns:

The SQL statements for changing the index_together indexes.

Return type:

django_evolution.sql_result.SQLResult

change_meta_db_table_comment(model, old_comment, new_comment)

Change the comment for a table.

Table comments are supported for some database backends in Django 4.2 and higher. This generates the SQL for setting a comment for a given table.

New in version 2.3.

Parameters:
Returns:

The SQL statements for changing Meta.db_table_comment.

Return type:

django_evolution.sql_result.SQLResult

change_meta_constraints(model, old_constraints, new_constraints)

Change the constraints of a table.

Constraints are a feature available in Django 2.2+ that allow for defining custom constraints on a table on Meta.constraints.

This will calculate the old and new list of constraint instances, and the list of added/removed constraints, and call out to get_update_table_constraints_sql() to generate the SQL for changing them.

Parameters:
  • model (django.db.models.Model) – The model being changed.

  • old_constraints (list of dict) –

    A serialized representation of the old value for Meta.constraints.

    This will contain name and type keys, as well as all attributes on the constraint.

  • new_constraints (list of dict) –

    A serialized representation of the new value for Meta.constraints.

    This is in the same format as old_constraints.

Returns:

The SQL statements for changing Meta.constraints.

Return type:

django_evolution.sql_result.SQLResult

get_update_table_constraints_sql(model, old_constraints, new_constraints, to_add, to_remove)

Return SQL for updating the constraints on a table.

The generated SQL will remove any old constraints and add any new constraints.

By default, this uses the schema editor for the connection. Subclasses can modify this if they need custom logic.

Parameters:
  • model (django.db.models.Model) – The model being changed.

  • old_constraints (list of :class:`` :class:`` :class:`` :class:`` :class:`` :class:`` :class:`` :class:`` :class:`` :class:`` :class:`` :class:`` :class:`` :class:`` :class:`` :class:`` :class:`` :class:`` :class:`` :class:`` :class:`` django.db.models.constraints.BaseConstraint) – The old constraints pre-evolution.

  • new_constraints (list of :class:`` :class:`` :class:`` :class:`` :class:`` :class:`` :class:`` :class:`` :class:`` :class:`` :class:`` :class:`` :class:`` :class:`` :class:`` :class:`` :class:`` :class:`` :class:`` :class:`` :class:`` django.db.models.constraints.BaseConstraint) – The new constraints post-evolution.

  • to_add (list of django.db.models.constraints.BaseConstraint) – A list of new constraints to add to the database that weren’t set before.

  • to_remove (list of django.db.models.constraints.BaseConstraint) – A list of old constraints to remove from the database that aren’t set now.

Returns:

The SQL statements for changing the constraints.

Return type:

django_evolution.sql_result.SQLResult

change_meta_indexes(model, old_indexes, new_indexes)

Change the indexes of a table defined in a model’s indexes list.

This will apply a set of indexes serialized from a Meta.indexes to the database. The serialized values are those passed to ChangeMeta, in the form of:

[
    {
        'condition': {<deconstructured>},
        'db_tablespace': '...',
        'expressions': [{<deconstructured>}, ...],
        'fields': ['field1', '-field2_sorted_desc'],
        'include': ['...', ...],
        'name': 'optional-index-name',
        'opclasses': ['...', ...],
    },
    ...
]
Parameters:
  • model (django.db.models.Model) – The model being changed.

  • old_indexes (list) – The old serialized value for the indexes.

  • new_indexes (list) – The new serialized value for the indexes.

Returns:

The SQL statements for changing the indexes.

Return type:

django_evolution.sql_result.SQLResult

get_fields_for_names(model, field_names, allow_sort_prefixes=False)

Return the field instances for the given field names.

This will go through each of the provided field names, optionally handling a sorting prefix (-, used by Django 1.11+’s Index field lists), and return the field instance for each.

Parameters:
  • model (django.db.models.Model) – The model to fetch fields from.

  • field_names (list of unicode) – The list of field names to fetch.

  • allow_sort_prefixes (bool, optional) – Whether to allow sorting prefixes in the field names.

Returns:

The resulting list of fields.

Return type:

list of django.db.models.Field

get_column_names_for_fields(fields)
get_constraints_for_table(table_name)

Return all known constraints/indexes on a table.

This will scan the table for any constraints or indexes. It generally will wrap Django’s database introspection support if available (on Django >= 1.7), falling back on in-house implementations on earlier releases.

New in version 2.2.

Parameters:

table_name (unicode) – The name of the table.

Returns:

A dictionary mapping index names to a dictionary containing:

columns (list):

The list of columns that the index covers.

unique (bool):

Whether this is a unique index.

Return type:

dict

get_indexes_for_table(table_name)

Return all known indexes on a table.

This is a fallback used only on Django 1.6, due to lack of proper introspection on that release. It should only be called internally by get_constraints_for_table().

Parameters:

table_name (unicode) – The name of the table.

Returns:

A dictionary mapping index names to a dictionary containing:

columns (list):

The list of columns that the index covers.

unique (bool):

Whether this is a unique index.

Return type:

dict

stash_field_ref_constraints(model, replaced_fields={}, renamed_db_tables={})

Return SQL for removing constraints on a primary key field.

This should be called before performing an operation that renames a field or changes the table on a ManyToManyField on databases that support adding/dropping constraints on primary keys. The constraints can then be restored through restore_field_ref_constraints().

As of Django Evolution 2.0, this only considers fields on ManyToManyFields defined by model, keeping behavior consistent with prior versions of Django Evolution.

Parameters:
  • model (django.db.models.Model) – The model owning the fields to remove constraints from.

  • replaced_fields (dict) – A dictionary mapping old fields to new fields. Each field is expected to be a primary key. These will be checked for field name and column changes.

  • renamed_db_tables (dict) – A dictionary mapping old table names to new table names. This is used when renaming many-to-many intermediary tables.

Returns:

A tuple containing the following items:

  1. The SQLResult that contains the SQL to remove the current constraints.

  2. A dictionary containing internal stashed state for restoring constraints. This should be considered opaque.

Return type:

tuple

restore_field_ref_constraints(stash)

Return SQL for adding back field constraints on a table.

This should be called after performing an operation that renames a field or a ManyToMany table name on databases that support adding/dropping constraints on primary keys.

This requires a prior call to stash_field_ref_constraints().

Parameters:

stash (dict) – Stashed constraint data from stash_field_ref_constraints().

Returns:

The SQL statements for adding back constraints on the field.

Return type:

django_evolution.sql_result.SQLResult

normalize_initial(initial)

Normalize an initial value.

If the value is callable, it will be called and the result will be used. If that result is a string, it will be assumed to be something safe for embedding directly into SQL.

Anything else is considered best used as a SQL parameter.

New in version 2.3.

Parameters:

initial (object or callable) – The initial value to normalize.

Returns:

A 2-tuple of:

  1. The normalized initial value.

  2. Whether it can be embedded directly into SQL. If False, it should be used in SQL query parameter list.

Return type:

tuple

normalize_value(value)
normalize_bool(value)