简体   繁体   中英

Dirty way to alter table to change column type in Postgres

I have the situation I have a big table(a few millions of records) I need to update one column data type from varchar (250) to text . However here is the trick, there are multiple views created based on this table, these views are also used in a few other views and a few procedures, so deleting cascade and just simply recreating it is not an option. Is there any other tricky/dirty way to change it?

Main questions:

  1. How long can you carry out maintenance.
  2. How much space does this table take up? And how much free space is left on the tablespace?

--to get a list of dependent FUCTIONS/PROCEDURES use something like this:

SELECT n.nspname, p.proname, p.prosrc
FROM pg_proc p 
LEFT JOIN pg_namespace n ON n.oid = p.pronamespace 
WHERE p.prosrc ilike '%Table_xxx%';

--you can also check object dependency in pgAdmin

--to get a list of dependent VIEWS use something like this:

SELECT table_schema, table_name, pg_get_viewdef(table_schema||'.'||table_name, true)
FROM information_schema.tables 
WHERE table_type = 'VIEW'
AND pg_get_viewdef(table_schema||'.'||table_name, true) ilike '%Table_xxx%';

--so now you have a list of dependent objects. you can test your updates.

--Don`t forget about DCL (you need to test it or just use pgAdmin):

SELECT 'GRANT '||privilege_type||' ON '||table_schema||'.'||table_name||' TO '||grantee||';'
FROM information_schema.role_table_grants 
WHERE table_name='Table_xxx';

--next step. (if you have enough maintenance time:)

--in SINNGLE TRANSACTION:

--drop dependent objects

--change column type

ALTER TABLE Table_xxx ALTER COLUMN c_xxx TYPE text;

--recreate dependent objects

--restore DCL

--next step. (if you need to modify a lot of columns and you have enought space and time) you can:

--create temporary transformed table:

--stop your ETL-processes.

--in SINNGLE TRANSACTION:

--make transformations:

-- drop dependent objects

CREATE TABLE Table_xxx_tmp AS SELECT c_1, c_xxx::text, c_n FROM Table_xxx;

-- replace tables:

ALTER TABLE TABLE Table_xxx rename to Table_xxx_old;
ALTER TABLE TABLE Table_xxx_tmp rename to Table_xxx;

--recreate dependent objects (+triggers etc)

--4th restore DCL

--start your ETL-processes.

--but the MAIN THING here: think with your head.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM