### Configure Zero Downtime Backend Source: https://context7.com/tbicr/django-pg-zero-downtime-migrations/llms.txt Replace the default Django PostgreSQL engine with the zero-downtime backend in your settings.py. This example also shows recommended production settings for lock timeouts, statement timeouts, and handling of unsafe operations. ```python # settings.py DATABASES = { "default": { "ENGINE": "django_zero_downtime_migrations.backends.postgres", # PostGIS variant: # "ENGINE": "django_zero_downtime_migrations.backends.postgis", "NAME": "mydb", "USER": "myuser", "PASSWORD": "secret", "HOST": "localhost", "PORT": "5432", } } # Recommended production settings ───────────────────────────────────────────── # Abort migrations that wait more than 2 s for a table lock ZERO_DOWNTIME_MIGRATIONS_LOCK_TIMEOUT = "2s" # Abort any single migration SQL statement that runs longer than 2 s ZERO_DOWNTIME_MIGRATIONS_STATEMENT_TIMEOUT = "2s" # Allow long-running SHARE UPDATE EXCLUSIVE operations (e.g. CREATE INDEX # CONCURRENTLY) to bypass the global statement_timeout ZERO_DOWNTIME_MIGRATIONS_FLEXIBLE_STATEMENT_TIMEOUT = True # Raise UnsafeOperationException instead of just warning for unsafe migrations ZERO_DOWNTIME_MIGRATIONS_RAISE_FOR_UNSAFE = True ``` -------------------------------- ### Configure Django Database Backend Source: https://github.com/tbicr/django-pg-zero-downtime-migrations/blob/master/README.md To enable zero downtime migrations, set the 'ENGINE' in your Django settings to the provided backend. Ensure other database settings are configured as needed. ```python DATABASES = { 'default': { 'ENGINE': 'django_zero_downtime_migrations.backends.postgres', #'ENGINE': 'django_zero_downtime_migrations.backends.postgis', ... } } ``` -------------------------------- ### Configure Zero Downtime Migrations Settings Source: https://github.com/tbicr/django-pg-zero-downtime-migrations/blob/master/README.md Set these Django settings to control migration behavior and safety. ZERO_DOWNTIME_MIGRATIONS_LOCK_TIMEOUT and ZERO_DOWNTIME_MIGRATIONS_STATEMENT_TIMEOUT can be set to specific durations (e.g., '2s') or None to use PostgreSQL defaults. ZERO_DOWNTIME_MIGRATIONS_FLEXIBLE_STATEMENT_TIMEOUT enables flexible statement timeouts, and ZERO_DOWNTIME_MIGRATIONS_RAISE_FOR_UNSAFE ensures errors are raised for unsafe operations. ```python ZERO_DOWNTIME_MIGRATIONS_LOCK_TIMEOUT = '2s' ZERO_DOWNTIME_MIGRATIONS_STATEMENT_TIMEOUT = '2s' ZERO_DOWNTIME_MIGRATIONS_FLEXIBLE_STATEMENT_TIMEOUT = True ZERO_DOWNTIME_MIGRATIONS_RAISE_FOR_UNSAFE = True ``` -------------------------------- ### PostGIS Backend Settings Source: https://context7.com/tbicr/django-pg-zero-downtime-migrations/llms.txt Configure Django settings to use the PostGIS backend for zero-downtime migrations. This includes database connection details and specific zero-downtime migration configurations. ```python # settings.py DATABASES = { "default": { "ENGINE": "django_zero_downtime_migrations.backends.postgis", "NAME": "geodata", "USER": "geouser", "PASSWORD": "secret", "HOST": "localhost", } } ZERO_DOWNTIME_MIGRATIONS_RAISE_FOR_UNSAFE = True ZERO_DOWNTIME_MIGRATIONS_LOCK_TIMEOUT = "2s" ZERO_DOWNTIME_MIGRATIONS_STATEMENT_TIMEOUT = "10s" ZERO_DOWNTIME_MIGRATIONS_FLEXIBLE_STATEMENT_TIMEOUT = True ``` -------------------------------- ### Configure Deferred SQL Execution Source: https://github.com/tbicr/django-pg-zero-downtime-migrations/blob/master/README.md Defines how deferred SQL statements are applied. When `True`, deferred SQL runs similarly to the default Django behavior. When `False`, it runs as soon as possible. ```python ZERO_DOWNTIME_DEFERRED_SQL = True ``` -------------------------------- ### Configure Deferred SQL Flushing Source: https://context7.com/tbicr/django-pg-zero-downtime-migrations/llms.txt Control when deferred SQL statements (like constraint creations) are flushed. Setting ZERO_DOWNTIME_DEFERRED_SQL to False flushes them immediately after each operation, rather than after all operations in a migration module. ```python # settings.py ZERO_DOWNTIME_DEFERRED_SQL = True # flush after all operations, like standard Django (default) ZERO_DOWNTIME_DEFERRED_SQL = False # flush immediately after each operation ``` -------------------------------- ### Configure Idempotent SQL Source: https://context7.com/tbicr/django-pg-zero-downtime-migrations/llms.txt Set ZERO_DOWNTIME_MIGRATIONS_IDEMPOTENT_SQL to True to make migration statements re-runnable. The backend will skip already-applied statements, which is useful for recovering from partial migrations. ```python # settings.py ZERO_DOWNTIME_MIGRATIONS_IDEMPOTENT_SQL = False # standard non-atomic behaviour (default) ZERO_DOWNTIME_MIGRATIONS_IDEMPOTENT_SQL = True # skip already-applied statements ``` -------------------------------- ### Safe Index Creation with Django Source: https://context7.com/tbicr/django-pg-zero-downtime-migrations/llms.txt Django automatically converts `db_index=True` to `CREATE INDEX CONCURRENTLY` for zero-downtime index creation. Ensure your model fields are defined with `db_index=True`. ```python from django.db import models class Product(models.Model): sku = models.CharField(max_length=64, db_index=True) # becomes CONCURRENTLY automatically ``` ```python from django.db import migrations, models class Migration(migrations.Migration): dependencies = [("catalog", "0002_product")] operations = [ migrations.AddIndex( model_name="product", index=models.Index(fields=["sku"], name="catalog_product_sku_idx"), ) ] # Generated SQL: # CREATE INDEX CONCURRENTLY catalog_product_sku_idx ON catalog_product (sku); # -- no SET statement_timeout wrap (FLEXIBLE_STATEMENT_TIMEOUT handles it) ``` -------------------------------- ### Test Unsafe Migration Warning Source: https://context7.com/tbicr/django-pg-zero-downtime-migrations/llms.txt This test verifies that the 'migrate' command captures UnsafeOperationWarning instead of raising an exception when ZERO_DOWNTIME_MIGRATIONS_RAISE_FOR_UNSAFE is False. ```python @pytest.mark.django_db(transaction=True) @override_settings(ZERO_DOWNTIME_MIGRATIONS_RAISE_FOR_UNSAFE=False) def test_migration_warns_on_unsafe(recwarn): """Capture warnings instead of exceptions for auditing.""" call_command("migrate", "myapp_with_rename") unsafe_warnings = [w for w in recwarn.list if issubclass(w.category, UnsafeOperationWarning)] assert len(unsafe_warnings) == 1 assert "ALTER TABLE RENAME" in str(unsafe_warnings[0].message) ``` -------------------------------- ### Enable Explicit Constraints Drop Source: https://context7.com/tbicr/django-pg-zero-downtime-migrations/llms.txt Set ZERO_DOWNTIME_MIGRATIONS_EXPLICIT_CONSTRAINTS_DROP to True to ensure that foreign keys, unique constraints, and indexes are explicitly dropped before a table or column. This prevents downtime by separating fast metadata operations from slow physical deletions. ```python # settings.py ZERO_DOWNTIME_MIGRATIONS_EXPLICIT_CONSTRAINTS_DROP = True # default — safe explicit drops ZERO_DOWNTIME_MIGRATIONS_EXPLICIT_CONSTRAINTS_DROP = False # standard Django CASCADE behaviour ``` -------------------------------- ### Enable Idempotent SQL Mode Source: https://github.com/tbicr/django-pg-zero-downtime-migrations/blob/master/README.md Defines the idempotent mode for migrations. When `True`, already applied SQL migrations are skipped. This mode relies on name and index, and constraint valid state, so it may ignore name collisions and is not recommended for CI checks. ```python ZERO_DOWNTIME_MIGRATIONS_IDEMPOTENT_SQL = False ``` -------------------------------- ### Configure Raising Unsafe Operations Source: https://context7.com/tbicr/django-pg-zero-downtime-migrations/llms.txt Control whether inherently unsafe migration operations (e.g., table rename, column rename, `ADD COLUMN NOT NULL` without `db_default`) raise an `UnsafeOperationException` or emit a warning. Raising an exception is useful for blocking CI/CD pipelines. ```python # settings.py ZERO_DOWNTIME_MIGRATIONS_RAISE_FOR_UNSAFE = False # emit UnsafeOperationWarning (default) ZERO_DOWNTIME_MIGRATIONS_RAISE_FOR_UNSAFE = True # raise UnsafeOperationException — blocks CI/CD ``` -------------------------------- ### Test Safe Migration Command Source: https://context7.com/tbicr/django-pg-zero-downtime-migrations/llms.txt This test ensures that the 'migrate' command raises an UnsafeOperationException when ZERO_DOWNTIME_MIGRATIONS_RAISE_FOR_UNSAFE is True and an unsafe operation is detected. ```python import pytest from django.core.management import call_command from django.test import override_settings from django_zero_downtime_migrations.backends.postgres.schema import ( UnsafeOperationException, UnsafeOperationWarning, ) @pytest.mark.django_db(transaction=True) @override_settings(ZERO_DOWNTIME_MIGRATIONS_RAISE_FOR_UNSAFE=True) def test_migration_is_safe(): """All migrations in 'myapp' must be zero-downtime safe.""" call_command("migrate", "myapp") # raises UnsafeOperationException if any op is unsafe ``` -------------------------------- ### Safe Primary Key Creation with Django Source: https://context7.com/tbicr/django-pg-zero-downtime-migrations/llms.txt Primary keys are created by first building a unique concurrent index, then promoting it to a primary key constraint. This minimizes the duration of the `ACCESS EXCLUSIVE` lock. ```python from django.db import migrations, models class Migration(migrations.Migration): dependencies = [("shop", "0006_nopk_table")] operations = [ migrations.AddConstraint( model_name="legacyrecord", constraint=models.UniqueConstraint(fields=["legacy_id"], name="legacyrecord_pkey"), ) ] # Generated SQL: # CREATE UNIQUE INDEX CONCURRENTLY legacyrecord_pkey ON shop_legacyrecord (legacy_id); # ALTER TABLE shop_legacyrecord # ADD CONSTRAINT legacyrecord_pkey PRIMARY KEY USING INDEX legacyrecord_pkey; ``` -------------------------------- ### Enable Raising for Unsafe Migrations Source: https://github.com/tbicr/django-pg-zero-downtime-migrations/blob/master/README.md This option prevents the execution of potentially unsafe migrations. It is disabled by default. ```python ZERO_DOWNTIME_MIGRATIONS_RAISE_FOR_UNSAFE = True ``` -------------------------------- ### Handle UNIQUE Constraint Safely Source: https://github.com/tbicr/django-pg-zero-downtime-migrations/blob/master/README.md While Postgres uses unique indexes for both `CREATE UNIQUE INDEX` and `ALTER TABLE ADD CONSTRAINT UNIQUE`, direct constraint dropping can be problematic. This section implies a need for careful handling when dealing with unique constraints in a zero-downtime context. ```sql ALTER TABLE ADD CONSTRAINT UNIQUE ``` -------------------------------- ### Safe Unique Constraint Creation with Django Source: https://context7.com/tbicr/django-pg-zero-downtime-migrations/llms.txt For zero-downtime unique constraints, the backend splits the operation into a concurrent index build and a constraint promotion. This is handled automatically when using `models.UniqueConstraint`. ```python from django.db import migrations, models class Migration(migrations.Migration): dependencies = [("accounts", "0003_user")] operations = [ migrations.AddConstraint( model_name="user", constraint=models.UniqueConstraint(fields=["email"], name="accounts_user_email_uniq"), ) ] # Generated SQL (zero-downtime backend): # CREATE UNIQUE INDEX CONCURRENTLY accounts_user_email_uniq ON accounts_user (email); # ALTER TABLE accounts_user # ADD CONSTRAINT accounts_user_email_uniq UNIQUE USING INDEX accounts_user_email_uniq; ``` -------------------------------- ### Enable Explicit Constraints Drop Source: https://github.com/tbicr/django-pg-zero-downtime-migrations/blob/master/README.md Defines the method for dropping foreign keys, unique constraints, and indexes before dropping a table or column. When `True`, these are dropped explicitly. This allows splitting schema-only changes with an `ACCESS EXCLUSIVE` lock and deletion of physical files, which can take significant time and cause downtime. ```python ZERO_DOWNTIME_MIGRATIONS_EXPLICIT_CONSTRAINTS_DROP = True ``` -------------------------------- ### Configure Lock Timeout Source: https://context7.com/tbicr/django-pg-zero-downtime-migrations/llms.txt Set the `lock_timeout` for SQL statements that acquire an `ACCESS EXCLUSIVE` lock. This prevents migrations from blocking indefinitely. Setting it to `None` uses the PostgreSQL server default, while '0' explicitly disables the timeout. ```python # settings.py # Disable (use PostgreSQL server default) — default behaviour ZERO_DOWNTIME_MIGRATIONS_LOCK_TIMEOUT = None # Abort after 2 seconds of waiting for a lock ZERO_DOWNTIME_MIGRATIONS_LOCK_TIMEOUT = "2s" # Equivalent: disable timeout explicitly ZERO_DOWNTIME_MIGRATIONS_LOCK_TIMEOUT = "0" ``` -------------------------------- ### Configure Statement Timeout Source: https://context7.com/tbicr/django-pg-zero-downtime-migrations/llms.txt Set the `statement_timeout` for SQL statements that acquire an `ACCESS EXCLUSIVE` lock. This prevents runaway migrations from occupying the database indefinitely. Use `None` for the server default. ```python # settings.py ZERO_DOWNTIME_MIGRATIONS_STATEMENT_TIMEOUT = None # use server default (default) ZERO_DOWNTIME_MIGRATIONS_STATEMENT_TIMEOUT = "2s" # abort after 2 s ZERO_DOWNTIME_MIGRATIONS_STATEMENT_TIMEOUT = "30s" # abort after 30 s ``` -------------------------------- ### Safe Check Constraint Creation with Django Source: https://context7.com/tbicr/django-pg-zero-downtime-migrations/llms.txt Similar to foreign keys, check constraints are added as `NOT VALID` and then validated, allowing for zero-downtime schema changes. ```python from django.db import migrations, models class Migration(migrations.Migration): dependencies = [("shop", "0005_order")] operations = [ migrations.AddConstraint( model_name="product", constraint=models.CheckConstraint( check=models.Q(price__gt=0), name="shop_product_price_positive", ), ) ] # Generated SQL: # ALTER TABLE shop_product # ADD CONSTRAINT shop_product_price_positive CHECK (price > 0) NOT VALID; # ALTER TABLE shop_product VALIDATE CONSTRAINT shop_product_price_positive; ``` -------------------------------- ### Safe Foreign Key Creation with Django Source: https://context7.com/tbicr/django-pg-zero-downtime-migrations/llms.txt Foreign key constraints are added as `NOT VALID` first, then validated separately to minimize lock times. This ensures referential integrity without blocking writes. ```python from django.db import migrations, models class Migration(migrations.Migration): dependencies = [("shop", "0004_order"), ("accounts", "0001_user")] operations = [ migrations.AddField( model_name="order", field=models.ForeignKey( "accounts.User", on_delete=models.CASCADE, related_name="orders", ), ) ] # Generated SQL: # ALTER TABLE shop_order # ADD CONSTRAINT shop_order_user_id_fk # FOREIGN KEY (user_id) REFERENCES accounts_user (id) NOT VALID; # ALTER TABLE shop_order VALIDATE CONSTRAINT shop_order_user_id_fk; ``` -------------------------------- ### Configure Flexible Statement Timeout Source: https://context7.com/tbicr/django-pg-zero-downtime-migrations/llms.txt Temporarily sets `statement_timeout = 0ms` for statements requiring only a `SHARE UPDATE EXCLUSIVE` lock. This is recommended when a global `statement_timeout` is active but long-running concurrent operations must still be permitted. ```python # settings.py ZERO_DOWNTIME_MIGRATIONS_FLEXIBLE_STATEMENT_TIMEOUT = False # default ZERO_DOWNTIME_MIGRATIONS_FLEXIBLE_STATEMENT_TIMEOUT = True # recommended when using STATEMENT_TIMEOUT globally ``` -------------------------------- ### Safe NOT NULL Column (Django < 5.0) Source: https://context7.com/tbicr/django-pg-zero-downtime-migrations/llms.txt For Django versions prior to 5.0, safely add a NOT NULL column in a two-step process: first add a nullable column, then backfill data, and finally apply NOT NULL using a check-constraint validation cycle. ```python # Step 1 — migration: add nullable column migrations.AddField( model_name="order", field=models.CharField(max_length=20, null=True), ) # Step 2 — data migration: fill existing rows (RunPython) # Step 3 — migration: set NOT NULL migrations.AlterField( model_name="order", field=models.CharField(max_length=20, null=False), ) # Generated SQL for Step 3 (zero-downtime backend): # ALTER TABLE shop_order ADD CONSTRAINT shop_order_status_notnull # CHECK (status IS NOT NULL) NOT VALID; -- ACCESS EXCLUSIVE, metadata only # ALTER TABLE shop_order VALIDATE CONSTRAINT shop_order_status_notnull; # -- SHARE UPDATE EXCLUSIVE, long scan OK # ALTER TABLE shop_order ALTER COLUMN status SET NOT NULL; -- metadata only (constraint exists) ``` -------------------------------- ### Configure Keep Default for Django < 5.0 Source: https://context7.com/tbicr/django-pg-zero-downtime-migrations/llms.txt For Django versions older than 5.0, set ZERO_DOWNTIME_MIGRATIONS_KEEP_DEFAULT to True to retain the database column's DEFAULT expression after adding a column with a Python default. This emulates Django 5.0's db_default behavior, making `ADD COLUMN DEFAULT NOT NULL` safe. ```python # settings.py (Django < 5.0 only — ignored and deprecated in Django 5.0+) ZERO_DOWNTIME_MIGRATIONS_KEEP_DEFAULT = False # drop database default after migration (default) ZERO_DOWNTIME_MIGRATIONS_KEEP_DEFAULT = True # retain database default — enables safe NOT NULL columns ``` -------------------------------- ### Set Lock Timeout for Exclusive Locks Source: https://github.com/tbicr/django-pg-zero-downtime-migrations/blob/master/README.md Configure the `lock_timeout` GUC for SQL statements that require an `ACCESS EXCLUSIVE` lock. Setting this to '2s' will apply a 2-second timeout. Use `None` to rely on the current PostgreSQL setting. ```python ZERO_DOWNTIME_MIGRATIONS_LOCK_TIMEOUT = '2s' ``` -------------------------------- ### Add NOT NULL Constraint Safely Source: https://github.com/tbicr/django-pg-zero-downtime-migrations/blob/master/README.md Use this sequence of commands to add a NOT NULL constraint to an existing column without downtime. This involves adding an invalid CHECK constraint, validating it, setting the column to NOT NULL, and finally cleaning up the constraint. ```sql ALTER TABLE ADD CONSTRAINT CHECK (column IS NOT NULL) NOT VALID ``` ```sql ALTER TABLE VALIDATE CONSTRAINT ``` ```sql ALTER TABLE ALTER COLUMN SET NOT NULL ``` ```sql ALTER TABLE DROP CONSTRAINT ``` -------------------------------- ### Configure Keeping Default Values Source: https://github.com/tbicr/django-pg-zero-downtime-migrations/blob/master/README.md Defines whether to keep or drop code defaults on the database level when adding a new column. This option is only applicable for Django versions prior to 5.0. For Django 5.0+, use `db_default`. ```python ZERO_DOWNTIME_MIGRATIONS_KEEP_DEFAULT = False ``` -------------------------------- ### Add Not Null Column with Default (Django >= 5.0) Source: https://github.com/tbicr/django-pg-zero-downtime-migrations/blob/master/README.md Utilizes Django 5.0+'s `db_default` feature for robustly adding a column with a `NOT NULL` constraint and a default value. This approach ensures that existing and new code inserts work seamlessly. ```sql -- migration ALTER TABLE tbl ADD COLUMN new_col integer DEFAULT 0 NOT NULL; -- business logic INSERT INTO tbl (old_col) VALUES (1); -- old code inserts work fine with default INSERT INTO tbl (old_col, new_col) VALUES (1, 1); -- new code inserts work fine ``` -------------------------------- ### Block Unsafe Operations in Tests Source: https://context7.com/tbicr/django-pg-zero-downtime-migrations/llms.txt Configure tests to raise an UnsafeOperationException when unsafe operations like renaming columns are attempted. This requires setting ZERO_DOWNTIME_MIGRATIONS_RAISE_FOR_UNSAFE to True. ```python import pytest from django.test import override_settings from django_zero_downtime_migrations.backends.postgres.schema import UnsafeOperationException @pytest.mark.django_db(transaction=True) @override_settings(ZERO_DOWNTIME_MIGRATIONS_RAISE_FOR_UNSAFE=True) def test_rename_column_is_blocked(): from django.core.management import call_command with pytest.raises(UnsafeOperationException): call_command("migrate", "myapp", "0002_rename_field") ``` -------------------------------- ### Enable Flexible Statement Timeout Source: https://github.com/tbicr/django-pg-zero-downtime-migrations/blob/master/README.md Set `statement_timeout` to `0ms` for SQL statements requiring `SHARE UPDATE EXCLUSIVE` locks. Useful when `statement_timeout` is enabled globally and long-running operations like index creation or constraint validation are performed. ```python ZERO_DOWNTIME_MIGRATIONS_FLEXIBLE_STATEMENT_TIMEOUT = True ``` -------------------------------- ### Set Statement Timeout for Exclusive Locks Source: https://github.com/tbicr/django-pg-zero-downtime-migrations/blob/master/README.md Configure the `statement_timeout` GUC for SQL statements that require an `ACCESS EXCLUSIVE` lock. Setting this to '2s' will apply a 2-second timeout. Use `None` to rely on the current PostgreSQL setting. ```python ZERO_DOWNTIME_MIGRATIONS_STATEMENT_TIMEOUT = '2s' ``` -------------------------------- ### Safe NOT NULL Column (Django 5.0+) Source: https://context7.com/tbicr/django-pg-zero-downtime-migrations/llms.txt Use `db_default` in models to add a column with a database-level default. This allows `DEFAULT ... NOT NULL` to be applied safely in a single statement without requiring an extra data scan. ```python # models.py from django.db import models class Order(models.Model): status = models.CharField(max_length=20, db_default="pending") # db_default → safe NOT NULL ``` ```python # migrations/0002_order_status.py from django.db import migrations, models class Migration(migrations.Migration): dependencies = [("shop", "0001_initial")] operations = [ migrations.AddField( model_name="order", field=models.CharField(max_length=20, db_default="pending"), ) ] # Generated SQL (zero-downtime backend): # SET statement_timeout TO '2s'; SET lock_timeout TO '2s'; # ALTER TABLE "shop_order" ADD COLUMN "status" varchar(20) DEFAULT 'pending' NOT NULL; # SET statement_timeout TO ...; SET lock_timeout TO ...; ``` -------------------------------- ### Safe VARCHAR to TEXT Type Change Source: https://github.com/tbicr/django-pg-zero-downtime-migrations/blob/master/README.md Changing a VARCHAR column to TEXT is a safe operation in PostgreSQL. ```sql ALTER TABLE ALTER COLUMN TYPE text ``` -------------------------------- ### Add Not Null Column with Default (Django < 5.0) Source: https://github.com/tbicr/django-pg-zero-downtime-migrations/blob/master/README.md Emulates `db_default` behavior for `default` fields in Django versions prior to 5.0 by keeping the default value after migration. This ensures compatibility with `NOT NULL` constraints. ```sql -- migration ALTER TABLE tbl ADD COLUMN new_col integer DEFAULT 0 NOT NULL; ALTER TABLE tbl ALTER COLUMN new_col DROP DEFAULT; -- business logic INSERT INTO tbl (old_col) VALUES (1); -- old code inserts fail INSERT INTO tbl (old_col, new_col) VALUES (1, 1); -- new code inserts work fine ``` -------------------------------- ### Safe Numeric Precision Increase Source: https://github.com/tbicr/django-pg-zero-downtime-migrations/blob/master/README.md Increasing the precision of a NUMERIC column is a safe operation in PostgreSQL, provided the scale remains the same and the new precision is greater than the old one. ```sql ALTER TABLE ALTER COLUMN TYPE numeric(MORE, SAME) ``` -------------------------------- ### Safe VARCHAR Length Increase Source: https://github.com/tbicr/django-pg-zero-downtime-migrations/blob/master/README.md Increasing the length of a VARCHAR column is a safe operation in PostgreSQL, provided the new length is greater than the old one. ```sql ALTER TABLE ALTER COLUMN TYPE varchar(MORE) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.