snippetsqlModerate
How to safely replace the old table with its cleaned copy?
Viewed 0 times
thewithcleanedreplaceitshowsafelyoldtablecopy
Problem
I have created a
but the first statement gives
I definitely don't want to use
How can I safely replace the old table with its cleaned copy?
Following Erwin Brandstetter's advice, this is the missing detail of the error message:
table_cleaned like table and inserted unique values from table into table_cleaned. Now I want to replace table with table_cleaned withDROP TABLE table;
ALTER TABLE table_cleaned rename to table;but the first statement gives
cannot drop table cals_status because other objects depend on it.I definitely don't want to use
cascade as it would delete all the dependent rows.How can I safely replace the old table with its cleaned copy?
Following Erwin Brandstetter's advice, this is the missing detail of the error message:
DETAIL: default value for column id of table cals_status_deduplicated depends on sequence cals_status_id_seqSolution
By default, the error message tells you more. Like:
General solution
Include the object mentioned in the
Also, to do it safely, wrap all of it in a transaction, and write-lock the old table before working on the new to avoid losing work done during the transition:
There may be more depending objects. Same procedure.
In the example, to get the view definition:
See:
And you may want to rename constraints and indices to fit the renamed table - or hold back on those and create with correct names after renaming the new table. (Again, be sure to get the definition before dropping the old table!)
Related:
If there are many depending objects and the table is not too big, a good alternative might be to prepare the new table (possibly as temporary table for better performance), then
Or you might be able to update the old table in place? This related answer shows code for all three variants:
Specific solution
Your particular error message:
... indicates that you are (ab-)using a sequence to generate default values for multiple tables. Or at least it's owned by the wrong column. The solution depends on how you want to deal with the situation.
Or you created the new table copying the complete structure including default values depending on the same sequence.
Typically, you want a dedicated sequence. So you should probably make the new column own the
Related:
You may be interested in
ERROR: cannot drop table tbl because other objects depend on it
SQL state: 2BP01
Detail: view v_tbl depends on table tbl
Hint: Use DROP ... CASCADE to drop the dependent objects too.General solution
Include the object mentioned in the
Detail line in your script.Also, to do it safely, wrap all of it in a transaction, and write-lock the old table before working on the new to avoid losing work done during the transition:
BEGIN;
LOCK TABLE tbl IN SHARE MODE;
-- prepare tbl_cleaned
DROP VIEW v_tbl; -- or any other depending object
-- more?
DROP TABLE tbl;
ALTER TABLE tbl_cleaned rename to tbl;
CREATE VIEW v_tbl AS SELECT ... -- actual definition, see below
-- more?
COMMIT;There may be more depending objects. Same procedure.
In the example, to get the view definition:
SELECT 'CREATE VIEW v_foo1 AS '
|| pg_get_viewdef('v_foo1'::regclass) AS view_definition;See:
- How to list the columns of a view in Postgres?
And you may want to rename constraints and indices to fit the renamed table - or hold back on those and create with correct names after renaming the new table. (Again, be sure to get the definition before dropping the old table!)
Related:
- Best way to populate a new column in a large table?
- How do I replace a table in Postgres?
If there are many depending objects and the table is not too big, a good alternative might be to prepare the new table (possibly as temporary table for better performance), then
TRUNCATE the original and INSERT from the prepared new table. This way, depending objects like views, FK constraints, rules, function using the table type etc. can just stay in place. See:- Add new column without table lock?
Or you might be able to update the old table in place? This related answer shows code for all three variants:
- Compacting a sequence in PostgreSQL
Specific solution
Your particular error message:
DETAIL: default value for column id of table cals_status_deduplicated depends on sequence cals_status_id_seq
... indicates that you are (ab-)using a sequence to generate default values for multiple tables. Or at least it's owned by the wrong column. The solution depends on how you want to deal with the situation.
Or you created the new table copying the complete structure including default values depending on the same sequence.
Typically, you want a dedicated sequence. So you should probably make the new column own the
SEQUENCE:ALTER SEQUENCE cals_status_id_seq OWNED BY tbl_cleaned.id; -- column in new table *before* switchingDROP TABLE only cascades to the sequence if it's owned by one of the columns in the table to be dropped.Related:
- How to reset Postgres' primary key sequence when it falls out of sync?
You may be interested in
IDENTITY columns which avoid this kind of complication with serial columns. See:- Auto increment table column
Code Snippets
ERROR: cannot drop table tbl because other objects depend on it
SQL state: 2BP01
Detail: view v_tbl depends on table tbl
Hint: Use DROP ... CASCADE to drop the dependent objects too.BEGIN;
LOCK TABLE tbl IN SHARE MODE;
-- prepare tbl_cleaned
DROP VIEW v_tbl; -- or any other depending object
-- more?
DROP TABLE tbl;
ALTER TABLE tbl_cleaned rename to tbl;
CREATE VIEW v_tbl AS SELECT ... -- actual definition, see below
-- more?
COMMIT;SELECT 'CREATE VIEW v_foo1 AS '
|| pg_get_viewdef('v_foo1'::regclass) AS view_definition;ALTER SEQUENCE cals_status_id_seq OWNED BY tbl_cleaned.id; -- column in new table *before* switchingContext
StackExchange Database Administrators Q#270024, answer score: 11
Revisions (0)
No revisions yet.