You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: develop-docs/backend/application-domains/database-migrations/index.mdx
+5-6Lines changed: 5 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -449,19 +449,18 @@ Since we run Postgres >= 14 in production we are able to add columns with a defa
449
449
450
450
We can't use `default` because Django's default behaviour for creating a new not null column with a default is dangerous. When using default, in the migration Django will add the default to backfill all fields, then immediately remove it so that it can handle them in the app layer. This means that during a deploy, the column is sitting in production without a default until all code rolls out, which means that inserts will fail for this table until the deploy completes.
451
451
452
-
### Adding Not Null To Columns
452
+
### Adding Constraints to Columns (Including Not Null)
453
453
454
-
It can be dangerous to add not null to columns, even if there is data in every row of the table for that column. This is because Postgres still needs to perform a not null check on all rows before it can add the constraint. On small tables this can be fine since
455
-
the check will be quick, but on larger tables this can cause downtime. There are a few options here to make this safe:
454
+
It can be dangerous to add constraints to columns, whether they are new or existing columns, even if the data in every row of the table does not violate the constraint. This is because Postgres still needs to perform a constraint check on all rows before it can add the constraint. On small tables this can be fine since the check will be quick, but on larger tables this can cause downtime. There are a few options here to make this safe:
456
455
457
456
```sql
458
-
ALTERTABLE tbl ADD CONSTRAINT cnstr CHECK (col IS NOT NULL) NOT VALID;
457
+
ALTERTABLE tbl ADD CONSTRAINT cnstr CHECK (col IS NOT NULL) NOT VALID;-- example with a not null constraint
459
458
ALTERTABLE tbl VALIDATE CONSTRAINT cnstr;
460
459
```
461
460
462
-
One approach is to create the constraint as not valid. Then we validate it afterwards. We still need to scan the whole table to validate, but we only need to hold a `SHARE UPDATE EXCLUSIVE` lock, which only blocks other `ALTER TABLE` commands, but will allow reads/writes to continue. This works well, but has a slight performance penalty of 0.5-1%. After Postgres 12 we can extend this method to add a real`NOT NULL` constraint.
461
+
One approach is to create the constraint as not valid. Then we validate it afterwards. We still need to scan the whole table to validate, but we only need to hold a `SHARE UPDATE EXCLUSIVE` lock, which only blocks other `ALTER TABLE` commands, but will allow reads/writes to continue. This works well, but has a slight performance penalty of 0.5-1%. After Postgres 12 we can extend this method to add the real constraint.
463
462
464
-
Alternatively, if the table is small enough and has low enough volume it should be safe to just create a normal `NOT NULL` constraint. Small being a few million rows or less.
463
+
Alternatively, if the table is small enough and has low enough volume it should be safe to just create the constraint as is. Small being a few million rows or less.
0 commit comments