@@ -782,6 +782,58 @@ export const NEON_TOOLS = [
782782 </example>
783783 </hint>
784784
785+ <hint>
786+ In some cases, you need to combine two approaches to achieve a zero-downtime migration.
787+
788+ <example>
789+ \`\`\`sql
790+ -- Step 1: Adding a nullable column first
791+ ALTER TABLE users ADD COLUMN created_at timestamptz;
792+
793+ -- Step 2: Updating the all rows with the default value
794+ UPDATE users SET created_at = now() WHERE created_at IS NULL;
795+
796+ -- Step 3: Creating a not null constraint
797+ ALTER TABLE users ADD CONSTRAINT users_created_at_not_null
798+ CHECK (created_at IS NOT NULL) NOT VALID;
799+
800+ -- Step 4: Validating the constraint
801+ ALTER TABLE users VALIDATE CONSTRAINT users_created_at_not_null;
802+
803+ -- Step 5: Setting the column to NOT NULL
804+ ALTER TABLE users ALTER COLUMN created_at SET NOT NULL;
805+
806+ -- Step 6: Dropping the redundant NOT NULL constraint
807+ ALTER TABLE users DROP CONSTRAINT users_created_at_not_null;
808+
809+ -- Step 7: Adding the default value
810+ ALTER TABLE users ALTER COLUMN created_at SET DEFAULT now();
811+ \`\`\`
812+ </example>
813+
814+ For PostgreSQL v18+
815+ <example>
816+ <example>
817+ \`\`\`sql
818+ -- Step 1: Adding a nullable column first
819+ ALTER TABLE users ADD COLUMN created_at timestamptz;
820+
821+ -- Step 2: Updating the all rows with the default value
822+ UPDATE users SET created_at = now() WHERE created_at IS NULL;
823+
824+ -- Step 3: Creating a not null constraint
825+ ALTER TABLE users ALTER COLUMN created_at SET NOT NULL NOT VALID;
826+
827+ -- Step 4: Validating the constraint
828+ ALTER TABLE users VALIDATE CONSTRAINT users_created_at_not_null;
829+
830+ -- Step 5: Adding the default value
831+ ALTER TABLE users ALTER COLUMN created_at SET DEFAULT now();
832+ \`\`\`
833+ </example>
834+ </example>
835+ </hint>
836+
785837 <hint>
786838 Create index CONCURRENTLY
787839
0 commit comments