Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to change column type and all foreign keys in PostgreSQL?

I'm currently stuck in a catch 22 with my Django Application. I have to change the type of a column from Varying char to Integer as i'm moving from UUID's to plain old ID's (the data is not changing ever as it's physical constants). Now django threw a Fit originally about not being able to cast from VarChar to Int, so i "helped" it out with:

 ALTER TABLE glass_fill ALTER COLUMN id TYPE INTEGER USING CAST(id AS INT);

Now, it says:

django.db.utils.DatabaseError: foreign key constraint "glass_fill_manufacturer_glass_fill_id_fkey" cannot be implemented
DETAIL:  Key columns "glass_fill_id" and "id" are of incompatible types: integer and character varying.

Any Ideas?

Note: The glass_fill_manufacturer Table hasn't been created yet django trys to on syncdb but fails. also the,

ALTER TABLE glass_fill ALTER COLUMN id TYPE INTEGER USING CAST(id AS INT); 

line didn't alter the column as I thought.

glass_fill table schema:

-- Table: glass_fill

-- DROP TABLE glass_fill;

CREATE TABLE glass_fill
(
  id character varying(36) NOT NULL,
  name character varying(255),
  temperature real,
  density real,
  viscosity real,
  conductivity real,
  heat_capacity real,
  colour text,
  CONSTRAINT glass_fill_pkey PRIMARY KEY (id )
)
WITH (
  OIDS=FALSE
);
like image 382
Jharwood Avatar asked May 25 '12 11:05

Jharwood


People also ask

How do I change the datatype of multiple columns in PostgreSQL?

First, specify the name of the table to which the column you want to change belongs in the ALTER TABLE clause. Second, give the name of column whose data type will be changed in the ALTER COLUMN clause. Third, provide the new data type for the column after the TYPE keyword.

Can a column be a primary and foreign key PostgreSQL?

You can create a column having both keys (primary and foreign) but then it will be one to one mapping and add uniqueness to this column.

How do I change the default value of a column in PostgreSQL?

Changing a Column's Default Value. To set a new default for a column, use a command like: ALTER TABLE products ALTER COLUMN price SET DEFAULT 7.77; Note that this doesn't affect any existing rows in the table, it just changes the default for future INSERT commands.


2 Answers

ALTER TABLE glass_fill_manufacturer 
ALTER COLUMN glass_fill_id TYPE INTEGER USING CAST(glass_fill_id AS INT)
;

I guess by your text that Django will somehow do it but if it doesn't:

ALTER TABLE glass_fill_manufacturer 
drop constraint glass_fill_manufacturer_glass_fill_id_fkey
;

alter table glass_fill_manufacturer 
ADD constraint glass_fill_manufacturer_glass_fill_id_fkey 
foreign key (glass_fill_id) references glass_fill (id)
;
like image 63
Clodoaldo Neto Avatar answered Oct 23 '22 21:10

Clodoaldo Neto


You should do the following:

  1. Drop the constraints
  2. Create a temporary table to hold mapping between old and new ids
  3. Update glass_fill, returning the values into the temporary table
  4. Update the referencing tables from the temporary table
  5. Alter column types on all tables
  6. Recreate the constraints
like image 1
Quassnoi Avatar answered Oct 23 '22 19:10

Quassnoi