Skip to main content

Operation

Enum Operation 

Source
pub enum Operation {
Show 25 variants CreateTable { name: String, columns: Vec<ColumnDefinition>, constraints: Vec<Constraint>, without_rowid: Option<bool>, interleave_in_parent: Option<InterleaveSpec>, partition: Option<PartitionOptions>, }, DropTable { name: String, }, AddColumn { table: String, column: ColumnDefinition, mysql_options: Option<AlterTableOptions>, }, DropColumn { table: String, column: String, }, AlterColumn { table: String, column: String, old_definition: Option<ColumnDefinition>, new_definition: ColumnDefinition, mysql_options: Option<AlterTableOptions>, }, RenameTable { old_name: String, new_name: String, }, RenameColumn { table: String, old_name: String, new_name: String, }, AddConstraint { table: String, constraint_sql: String, }, DropConstraint { table: String, constraint_name: String, }, CreateIndex { table: String, columns: Vec<String>, unique: bool, index_type: Option<IndexType>, where_clause: Option<String>, concurrently: bool, expressions: Option<Vec<String>>, mysql_options: Option<AlterTableOptions>, operator_class: Option<String>, }, DropIndex { table: String, columns: Vec<String>, }, RunSQL { sql: String, reverse_sql: Option<String>, }, RunRust { code: String, reverse_code: Option<String>, }, AlterTableComment { table: String, comment: Option<String>, }, AlterUniqueTogether { table: String, unique_together: Vec<Vec<String>>, }, AlterModelOptions { table: String, options: HashMap<String, String>, }, CreateInheritedTable { name: String, columns: Vec<ColumnDefinition>, base_table: String, join_column: String, }, AddDiscriminatorColumn { table: String, column_name: String, default_value: String, }, MoveModel { model_name: String, from_app: String, to_app: String, rename_table: bool, old_table_name: Option<String>, new_table_name: Option<String>, }, CreateSchema { name: String, if_not_exists: bool, }, DropSchema { name: String, cascade: bool, if_exists: bool, }, CreateExtension { name: String, if_not_exists: bool, schema: Option<String>, }, BulkLoad { table: String, source: BulkLoadSource, format: BulkLoadFormat, options: BulkLoadOptions, }, SetAutoIncrementValue { table: String, column: String, value: i64, }, CreateCompositePrimaryKey { table: String, columns: Vec<String>, constraint_name: Option<String>, },
}
Expand description

A migration operation (legacy enum for backward compatibility)

This enum is maintained for backward compatibility with existing code. New code should use the specific operation types from the models, fields, and special modules instead.

Variants§

§

CreateTable

CreateTable variant.

Fields

§name: String

The name.

§columns: Vec<ColumnDefinition>

The columns.

§constraints: Vec<Constraint>

The constraints.

§without_rowid: Option<bool>

The without rowid.

§interleave_in_parent: Option<InterleaveSpec>

The interleave in parent.

§partition: Option<PartitionOptions>

The partition.

§

DropTable

DropTable variant.

Fields

§name: String

The name.

§

AddColumn

AddColumn variant.

Fields

§table: String

The table.

§column: ColumnDefinition

The column.

§mysql_options: Option<AlterTableOptions>

The mysql options.

§

DropColumn

DropColumn variant.

Fields

§table: String

The table.

§column: String

The column.

§

AlterColumn

AlterColumn variant.

Fields

§table: String

The table.

§column: String

The column.

§old_definition: Option<ColumnDefinition>

Original column definition (before alteration). This is required for generating accurate rollback SQL. If None, rollback will attempt to reconstruct from ProjectState.

§new_definition: ColumnDefinition

The new definition.

§mysql_options: Option<AlterTableOptions>

The mysql options.

§

RenameTable

RenameTable variant.

Fields

§old_name: String

The old name.

§new_name: String

The new name.

§

RenameColumn

RenameColumn variant.

Fields

§table: String

The table.

§old_name: String

The old name.

§new_name: String

The new name.

§

AddConstraint

AddConstraint variant.

Fields

§table: String

The table.

§constraint_sql: String

The constraint sql.

§

DropConstraint

DropConstraint variant.

Fields

§table: String

The table.

§constraint_name: String

The constraint name.

§

CreateIndex

CreateIndex variant.

Fields

§table: String

The table.

§columns: Vec<String>

The columns.

§unique: bool

The unique.

§index_type: Option<IndexType>

Index type (B-Tree, Hash, GIN, GiST, etc.)

If not specified, the database will use its default index type (typically B-Tree).

§where_clause: Option<String>

Partial index condition (WHERE clause)

Creates a partial index that only indexes rows matching this condition. Example: “status = ‘active’” creates an index only for active rows.

§concurrently: bool

Create index concurrently (PostgreSQL-specific)

When true, creates the index without locking the table for writes. This is slower but allows concurrent operations during index creation.

§expressions: Option<Vec<String>>

Expression index (PostgreSQL, SQLite, MySQL 8.0+)

Index on computed expressions rather than simple column references. When specified, these expressions are used instead of columns.

§Examples
// Index on lowercase email for case-insensitive lookups
expressions: Some(vec!["LOWER(email)"]),

Note: When expressions is Some, columns is ignored for SQL generation.

§mysql_options: Option<AlterTableOptions>

MySQL ALTER TABLE options (ALGORITHM, LOCK)

§operator_class: Option<String>

Operator class for index columns (PostgreSQL-specific)

Specifies a non-default operator class for the index. Commonly used with extension-provided operator classes like gin_trgm_ops for trigram similarity search with the pg_trgm extension.

§Examples
// GIN index with trigram operator class for fuzzy text search
CreateIndex {
    table: "products".to_string(),
    columns: vec!["name".to_string()],
    index_type: Some(IndexType::Gin),
    operator_class: Some("gin_trgm_ops"),
    ...
}
§

DropIndex

DropIndex variant.

Fields

§table: String

The table.

§columns: Vec<String>

The columns.

§

RunSQL

RunSQL variant.

Fields

§sql: String

The sql.

§reverse_sql: Option<String>

The reverse sql.

§

RunRust

RunRust variant.

Fields

§code: String

The code.

§reverse_code: Option<String>

The reverse code.

§

AlterTableComment

AlterTableComment variant.

Fields

§table: String

The table.

§comment: Option<String>

The comment.

§

AlterUniqueTogether

AlterUniqueTogether variant.

Fields

§table: String

The table.

§unique_together: Vec<Vec<String>>

The unique together.

§

AlterModelOptions

AlterModelOptions variant.

Fields

§table: String

The table.

§options: HashMap<String, String>

The options.

§

CreateInheritedTable

CreateInheritedTable variant.

Fields

§name: String

The name.

§columns: Vec<ColumnDefinition>

The columns.

§base_table: String

The base table.

§join_column: String

The join column.

§

AddDiscriminatorColumn

AddDiscriminatorColumn variant.

Fields

§table: String

The table.

§column_name: String

The column name.

§default_value: String

The default value.

§

MoveModel

Move a model from one app to another

This operation handles cross-app model moves by:

  1. Optionally renaming the table (if naming convention changes between apps)
  2. Updating FK references to use the new table name

Note: This generates a RenameTable SQL if table name changes. The state tracking (from_app -> to_app) is handled at the ProjectState level.

Fields

§model_name: String

Name of the model being moved

§from_app: String

Source app label

§to_app: String

Target app label

§rename_table: bool

Whether to rename the underlying table

§old_table_name: Option<String>

Old table name (if rename_table is true)

§new_table_name: Option<String>

New table name (if rename_table is true)

§

CreateSchema

Create a database schema (PostgreSQL, MySQL 5.0.2+)

Creates a new database schema namespace. In MySQL, this is equivalent to creating a database.

Fields

§name: String

Name of the schema to create

§if_not_exists: bool

Whether to add IF NOT EXISTS clause

§

DropSchema

Drop a database schema

Drops an existing database schema. Use with caution as this will drop all objects in the schema.

Fields

§name: String

Name of the schema to drop

§cascade: bool

Whether to add CASCADE clause (drops all contained objects)

§if_exists: bool

Whether to add IF EXISTS clause

§

CreateExtension

Create a PostgreSQL extension (PostgreSQL-specific)

Creates a PostgreSQL extension like PostGIS, uuid-ossp, etc. This operation is only executed on PostgreSQL databases.

Fields

§name: String

Name of the extension to create

§if_not_exists: bool

Whether to add IF NOT EXISTS clause

§schema: Option<String>

Optional schema to install the extension in

§

BulkLoad

Bulk data loading operation

Loads large amounts of data efficiently using database-native bulk loading commands:

  • PostgreSQL: COPY table FROM source WITH (FORMAT csv, ...)
  • MySQL: LOAD DATA [LOCAL] INFILE 'path' INTO TABLE table ...
  • SQLite: Not supported (falls back to INSERT statements)

§Performance

Bulk loading is typically 10-100x faster than individual INSERT statements for large datasets.

§Examples

use reinhardt_db::migrations::{Operation, BulkLoadSource, BulkLoadFormat, BulkLoadOptions};

// PostgreSQL COPY FROM file
let op = Operation::BulkLoad {
    table: "events".to_string(),
    source: BulkLoadSource::File("/tmp/events.csv"),
    format: BulkLoadFormat::Csv,
    options: BulkLoadOptions::new()
        .with_header(true)
        .with_delimiter(','),
};

// MySQL LOAD DATA LOCAL INFILE
let op = Operation::BulkLoad {
    table: "events".to_string(),
    source: BulkLoadSource::File("/tmp/events.csv"),
    format: BulkLoadFormat::Csv,
    options: BulkLoadOptions::new()
        .with_local(true)
        .with_delimiter(','),
};

Fields

§table: String

Target table name

§source: BulkLoadSource

Source of the data

§format: BulkLoadFormat

Format of the data

§options: BulkLoadOptions

Additional loading options

§

SetAutoIncrementValue

Reset the auto-increment counter for a table

Sets the next value produced by the table’s auto-increment mechanism. Typical uses include seeding IDs after a bulk import or shifting the sequence above a range reserved for historical data.

§Backend Behavior

  • PostgreSQL / CockroachDB: SELECT setval(pg_get_serial_sequence('{table}', '{column}'), {value}, false) (resolves the sequence dynamically so both default SERIAL conventions and user-defined sequence names work; false makes the NEXT generated value equal {value}).
  • MySQL: ALTER TABLE {table} AUTO_INCREMENT = {value}.
  • SQLite: INSERT OR REPLACE INTO sqlite_sequence(name, seq) VALUES (...) (robust against tables that have not yet inserted any rows, where a simple UPDATE would silently no-op).

Fields

§table: String

The table whose auto-increment counter should be set.

§column: String

The auto-increment column (used to resolve the backing sequence on PostgreSQL / CockroachDB).

§value: i64

The next value the counter should produce.

§

CreateCompositePrimaryKey

Create a composite (multi-column) PRIMARY KEY constraint on an existing table

Emits ALTER TABLE {table} ADD CONSTRAINT {name} PRIMARY KEY ({cols}) on every supported backend. When constraint_name is None the name defaults to {table}_pkey, matching PostgreSQL’s conventional auto-generated identifier.

columns must be non-empty; emitting an empty column list would produce invalid SQL and is rejected as an InvalidMigration error at SQL generation time.

Fields

§table: String

The table to add the composite primary key to.

§columns: Vec<String>

The ordered list of columns participating in the primary key.

§constraint_name: Option<String>

Optional explicit constraint name. Defaults to {table}_pkey when None.

Implementations§

Source§

impl Operation

Source

pub fn state_forwards(&self, app_label: &str, state: &mut ProjectState)

Apply this operation to the project state (forward)

Source

pub fn to_sql(&self, dialect: &SqlDialect) -> String

Generate forward SQL

Source

pub fn to_reverse_sql( &self, dialect: &SqlDialect, project_state: &ProjectState, ) -> Result<Option<String>, MigrationError>

Generate reverse SQL (for rollback)

§Arguments
  • dialect - SQL dialect for generating database-specific SQL
  • project_state - Project state for accessing model definitions (needed for DropTable, etc.)
§Returns
  • Ok(Some(sql)) - Reverse SQL generated successfully
  • Ok(None) - Operation is not reversible (see Design Limitation below)
  • Err(_) - Error generating reverse SQL
§Design Limitation

Destructive operations (DropTable, DropColumn, DropConstraint, AlterColumn) require a pre-operation ProjectState snapshot to generate reverse SQL. When the project_state parameter does not contain the necessary model/column/constraint definition, this method returns Ok(None) instead of failing.

This is an intentional design decision: the migration system cannot reconstruct lost schema information. Callers must provide the state from before the operation was applied to enable proper rollback. This matches Django’s migration behavior where state_forwards must be called before operations are reversed.

Source

pub fn state_backwards(&self, app_label: &str, state: &mut ProjectState)

Apply operation to project state (backward/reverse)

This method updates the ProjectState to reflect the reverse of this operation. Used during migration rollback to track state changes.

§Arguments
  • app_label - Application label for the model being modified
  • state - Mutable reference to the ProjectState to update
§Limitations

Some operations cannot fully reverse state without additional snapshot information:

  • DropTable: Cannot recreate model structure (columns, constraints) without snapshot
  • DropColumn: Cannot recreate column definition without snapshot
  • AlterColumn: Cannot restore original column definition without snapshot

For these operations, use to_reverse_sql with ProjectState before the operation is applied to generate proper reverse SQL.

Source§

impl Operation

Source

pub fn requires_sqlite_recreation(&self) -> bool

Check if this operation requires SQLite table recreation

Source

pub fn reverse_requires_sqlite_recreation(&self) -> bool

Check if the reverse of this operation requires SQLite table recreation

When rolling back a migration on SQLite, some reverse operations also require table recreation. This method identifies those cases.

Forward OperationReverse OperationRequires Recreation
AddColumnDropColumnYes
AlterColumnAlterColumnYes
AddConstraintDropConstraintYes
DropConstraintAddConstraintYes
Source

pub fn to_reverse_operation( &self, project_state: &ProjectState, ) -> Result<Option<Operation>, MigrationError>

Generate the reverse operation (for rollback on SQLite)

This method returns the conceptual reverse Operation, which can be used with handle_sqlite_recreation() for databases that don’t support direct ALTER TABLE operations.

§Arguments
  • project_state - Project state for accessing model definitions
§Returns
  • Ok(Some(op)) - Reverse operation generated successfully
  • Ok(None) - Operation is not reversible or state information is missing
  • Err(_) - Error generating reverse operation
Source§

impl Operation

Source

pub fn to_statement(&self) -> OperationStatement

Convert Operation to reinhardt-query statement or sanitized raw SQL

Trait Implementations§

Source§

impl Clone for Operation

Source§

fn clone(&self) -> Operation

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Operation

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl<'de> Deserialize<'de> for Operation

Source§

fn deserialize<__D>( __deserializer: __D, ) -> Result<Operation, <__D as Deserializer<'de>>::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl MigrationOperation for Operation

Source§

fn normalize(&self) -> Operation

Normalize operation for semantic comparison

Returns a normalized version where order-independent elements are sorted. This enables detection of semantically equivalent operations regardless of element ordering.

Source§

fn migration_name_fragment(&self) -> Option<String>

Generate a fragment for the migration name Read more
Source§

fn describe(&self) -> String

Human-readable description of this operation Read more
Source§

fn semantically_equal(&self, other: &Self) -> bool
where Self: Sized + Clone + PartialEq,

Check if two operations are semantically equal Read more
Source§

impl PartialEq for Operation

Source§

fn eq(&self, other: &Operation) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Serialize for Operation

Source§

fn serialize<__S>( &self, __serializer: __S, ) -> Result<<__S as Serializer>::Ok, <__S as Serializer>::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl ToTokens for Operation

Source§

fn to_tokens(&self, tokens: &mut TokenStream)

Write self to the given TokenStream. Read more
Source§

fn to_token_stream(&self) -> TokenStream

Convert self directly into a TokenStream object. Read more
Source§

fn into_token_stream(self) -> TokenStream
where Self: Sized,

Convert self directly into a TokenStream object. Read more
Source§

impl StructuralPartialEq for Operation

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Any for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Source§

fn type_name(&self) -> &'static str

Source§

impl<T> AnySync for T
where T: Any + Send + Sync,

Source§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Send + Sync>

Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<E> ServerFnErrorAssertions<E> for E
where E: Debug,

Source§

fn should_contain_message(&self, expected: &str)
where E: Display,

Assert that the error message contains the specified text.
Source§

fn should_have_message(&self, expected: &str)
where E: Display,

Assert that the error message matches exactly.
Source§

impl<T> Spanned for T
where T: Spanned + ?Sized,

Source§

fn span(&self) -> Span

Returns a Span covering the complete contents of this syntax tree node, or Span::call_site() if this node is empty.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,