While creating a column management tool I came across the need to quickly replicate tables in PostgreSQL so I would not test new tools with non-test tables. To effectively test the new column tool that I ultimately intend to use on the table parts
I created this new tool to duplicate parts
so I'd end up with a parts1
table. When I thought I had finally gotten all the issues ironed out I encountered the following error when the column tool deletes the table:
ERROR: cannot drop table parts because other objects depend on it
DETAIL: default for table parts1 column id depends on sequence
parts_id_seq1
I've spent the greater part of my day working towards this solution so in short can I simply use string functions to rename the SEQUENCE_NAME
variable to disassociate the parts
table from the parts
table or is it a more convoluted issue than that? Here is the query:
DO $$
DECLARE
SEQUENCE_NAME VARCHAR;
BEGIN
SELECT s.relname INTO SEQUENCE_NAME
FROM pg_class AS s JOIN pg_depend d ON d.objid = s.oid
INNER JOIN pg_class AS t ON d.objid = s.oid AND d.refobjid = t.oid
INNER JOIN pg_attribute AS a ON (d.refobjid, d.refobjsubid) = (a.attrelid, a.attnum)
INNER JOIN pg_namespace AS n ON n.oid = s.relnamespace
WHERE s.relkind = 'S'
AND n.nspname = 'public'
AND t.relname='parts';
LOCK TABLE parts;
CREATE TABLE parts1 (LIKE parts INCLUDING ALL);
INSERT INTO parts1 SELECT * FROM parts;
PERFORM setval(SEQUENCE_NAME::regclass, (SELECT max(id) FROM parts)+1);
END;
$$ LANGUAGE plpgsql;
Best Answer
To create a copy as close as possible you must use
INCLUDING ALL
withCREATE TABLE .. (LIKE ..)
since there can be any number of columns with defaults that you obviously want to copy.You just want
serial
columns to get their own, independent sequence, which makes a lot of sense and probably should be the default behavior. For now, this should do the job:Function to copy any given table
Copies any given table (must exist) with new given name and independent
serial
columns (if any).Data is not included, it's trivial to copy that, too.
Call:
Produces and executes SQL code of the form:
Only
serial
columns get their own sequence. Other column default are copied unchanged - includingnextval()
from a sequence that is not owned by the column or differs in any way from aserial
.The function is safe against SQL injection and should work with arbitrary table and column names.
SQL Fiddle.
It would be a useful option for the
LIKE
feature to create separate sequences forserial
columns. You may want to post a friendly feature request to pgsql-general.