These run during migrate, not in queries, so there's no result row — only the Django code and the SQL it emits.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | # ====================================================================== # These run during `migrate`, not in queries, so there's no result row — only # the Django code and the SQL it emits. They cover zero-downtime schema changes: # concurrent index builds, validating constraints in two steps, managing # collations, and enabling extensions. # ====================================================================== # ---------------------------------------------------------------------- # AddIndexConcurrently / RemoveIndexConcurrently # ---------------------------------------------------------------------- # Django: from django.contrib.postgres.operations import AddIndexConcurrently from django.contrib.postgres.indexes import GinIndex class Migration(migrations.Migration): atomic = False operations = [ AddIndexConcurrently( "book", GinIndex(fields=["tags"], name="book_tags_gin2")), ] # SQL: # CREATE INDEX CONCURRENTLY "book_tags_gin2" ON "examples_book" USING gin ("tags"); # Result: # Builds (or drops) an index WITHOUT locking the table for writes. # Must run in a non-atomic migration (`atomic = False`). # ---------------------------------------------------------------------- # AddConstraintNotValid + ValidateConstraint # ---------------------------------------------------------------------- # Django: from django.contrib.postgres.operations import ( AddConstraintNotValid, ValidateConstraint) from django.db.models import CheckConstraint, Q operations = [ AddConstraintNotValid( "book", CheckConstraint(condition=Q(price__gte=0), name="price_ok")), ValidateConstraint("book", "price_ok"), ] # SQL: # ALTER TABLE "examples_book" ADD CONSTRAINT "price_ok" CHECK ("price" >= 0) NOT VALID; # # ALTER TABLE "examples_book" VALIDATE CONSTRAINT "price_ok"; # Result: # Add a CHECK constraint without scanning existing rows (instant), # then validate it separately — avoids a long write lock on big tables. # ---------------------------------------------------------------------- # CreateCollation / RemoveCollation # ---------------------------------------------------------------------- # Django: from django.contrib.postgres.operations import CreateCollation operations = [ CreateCollation("case_insensitive", provider="icu", locale="und-u-ks-level2", deterministic=False), ] # SQL: # CREATE COLLATION "case_insensitive" (provider = icu, locale = 'und-u-ks-level2', deterministic = false); # Result: # Manage database collations from migrations. # This project uses CreateCollation('case_insensitive', …) in migration 0001. # ---------------------------------------------------------------------- # Extension operations (BloomExtension, CreateExtension, …) # ---------------------------------------------------------------------- # Django: from django.contrib.postgres.operations import ( BloomExtension, CreateExtension) operations = [BloomExtension(), CreateExtension("cube")] # SQL: # CREATE EXTENSION IF NOT EXISTS "bloom"; # # CREATE EXTENSION IF NOT EXISTS "cube"; # Result: # Enable a contrib module / extension from a migration. # Already used here: HStore, Trigram, BtreeGist, Unaccent, Crypto. # BloomExtension enables space-efficient bloom indexes. |