9

Using Django, I often have to add new fields to our PostgreSQL database. The fields usually have an initial value and they must be set to NOT NULL. My procedure for this involves three steps:

1) Add field and set initial value:

ALTER TABLE my_table ADD COLUMN my_field boolean;
UPDATE my_table SET my_field = FALSE;

2) Set NOT NULL:

ALTER TABLE my_table ALTER COLUMN my_field SET NOT NULL;

All three queries cannot be run in one go, because this results in a PostgreSQL error.

What's the most efficient way of performing this task? I'd like to do this in a single query - and with adding several fields in one go. Something along those lines:

ALTER TABLE my_table ADD COLUMN my_field boolean INITIAL FALSE SET NOT NULL, ADD COLUMN my_field2 boolean INITIAL FALSE SET NOT NULL;

3 Answers 3

7

Did you try this;

alter table my_table add column my_field1 boolean default false NOT NULL, 
                     add column my_field2 boolean default false NOT NULL;
Sign up to request clarification or add additional context in comments.

3 Comments

Since Django doesn't set the DEFAULT value on a database level, I remove this in a second step. Although this sequence appears to be less efficient than my original one, I prefer your way, because I often have trouble assigning the NOT NULL flag right after creating a field on our heavily used database. New null values are added just too quickly ...
Isn't this fundamentally different ? In the original way of the poster, the field gets an initial value, but then for the next inserts it will be mandatory to specify the field. Here you put a default value, meaning if the value is not specified for this field on insertion, false will be used
Is there a way to set the initial value for a new column without setting the default value?
2

You should do that by two steps:

  1. Add column
  2. Alter column: set constraint, add default

Query:

ALTER TABLE my_table ADD COLUMN my_field boolean;
ALTER TABLE my_table ALTER COLUMN my_field SET NOT NULL,
                     ALTER COLUMN my_field TYPE boolean USING false;

Or this:

ALTER TABLE my_table ADD COLUMN my_field boolean;
ALTER TABLE my_table ALTER COLUMN my_field SET NOT NULL,
                     ALTER COLUMN my_field SET DEFAULT false;

The benefit of first is that you can calculate value for each row based on your row data (in other words you can refer fields). for DEFAULT clause you must use bare value.

See documentation examples with timestamps

Comments

0

You can wrap your DDL into a fucntion that will be a good idea in your case, given below is a an example for your case.

Hope it works !!

CREATE OR REPLACE FUNCTION altertable(tablename text, colname text, coltype text,coldef text)
RETURNS void AS
$BODY$ 
BEGIN 
EXECUTE ' ALTER TABLE '|| quote_ident(tablename) || ' ADD COLUMN ' || quote_ident(colname) ||' '|| coltype ||' DEFAULT '||coldef||' NOT NULL'; END $BODY$
LANGUAGE plpgsql VOLATILE
  • Point Of Interest : able to alter any table,any column_type
  • Usage :

    select altertable('tbl1','bool_col','boolean','true')
    select altertable('tbl2','int_col','Integer','1')
    

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.