I'm using PostgreSQL 9.x, I want to rename a table. This SQL code:
CREATE TABLE new (id int);
ALTER TABLE new RENAME TO old;
DROP TABLE old;
renames the table correctly. But this SQL code:
CREATE SCHEMA domain;
CREATE TABLE domain.old (id int);
ALTER TABLE domain.old RENAME TO domain.new;
fails, with error:
ERROR: syntax error at or near "."
The "." underlined is the one between 'domain' and 'new'
One way to do this:
ALTER TABLE domain.old RENAME TO new
Other way:
SET search_path TO domain;
ALTER TABLE old RENAME TO new;
Documentation for search_path.
SET search_path TO domain;
ALTER TABLE IF EXISTS old_table_name RENAME TO new_table_name;
Switch to your database
machine$\c my_database
Tename the db
my_databse=# alter table old_name rename to new_name;
Related
To preface, I am trying to replace an entire table with a new table with same columns, but with updated values.
I have the following SQL code:
BEGIN;
ALTER TABLE "original" RENAME TO "original_old";
ALTER TABLE "original_new" RENAME TO "original";
ALTER TABLE "original" RENAME CONSTRAINT "temp_original_id" to "original_id";
DROP TABLE "original_old";
COMMIT;
Output:
ERROR: constraint "temp_original_id" for table "original" does not exist
However, if I do the following before the last ALTER statement:
SELECT * from original;
I see temp_original_id present in the table.
I can't seem to find any other sources that lead me to updating primary key (at least that worked)
The table I am replacing also has dependencies with other tables.. So I was wondering if this would be a viable solution to even begin with
Did you mean ALTER TABLE "original" RENAME COLUMN "temp_original_id" to "original_id"; ?
What is the difference between SQL statements
create temp table temp_1 And
create table #temp_1
used in creating temporary table or are both the same ?
Figured it out, both syntax does the same work !!
Users can either use the temp keyword or a # sign right before the table name to create a temporary table (Redshift Temp Table). In other words, to create a Redshift Temp Table, simply specify the TEMPORARY keyword (or TEMP abbreviation) or # sign in your CREATE TABLE DDL statement.
syntax 1 : CREATE TABLE #table_name (column_name1 data_type1,column_name2 data_typ2);
Syntax 2: CREATE TEMPORARY TABLE table_name (column_name1 data_type1,column_name2 data_typ2);
Syntax 3: CREATE TEMP TABLE table_name (column_name1 data_type1,column_name2 data_typ2);
Supporting documents on same -->
https://docs.aws.amazon.com/redshift/latest/dg/r_CREATE_TABLE_NEW.html
https://hevodata.com/learn/redshift-temp-tables/#c2
I hit the int limit on a large table I use.
The table is in single user mode and has no FK constraints.
CREATE TABLE my_table_bigint (LIKE my_table INCLUDING ALL);
ALTER TABLE my_table_bigint ALTER id DROP DEFAULT;
ALTER TABLE my_table_bigint alter column id set data type bigint;
CREATE SEQUENCE my_table_bigint_id_seq;
INSERT INTO my_table_bigint SELECT * FROM my_table;
ALTER TABLE my_table_bigint ALTER id SET DEFAULT nextval('my_table_bigint_id_seq');
ALTER SEQUENCE my_table_bigint_id_seq OWNED BY my_table_bigint.id;
SELECT setval('my_table_bigint_id_seq', (SELECT max(id) FROM my_table_bigint), true);
At this point I tested that I could insert new rows without any problems. Success, I thought.
I went about renaming the tables.
alter table my_table rename my_table_old
alter table my_table_bigint rename my_table
ALTER INDEX post_comments_pkey RENAME TO post_comments_old_pkey
ALTER INDEX post_comments_pkey_bigint RENAME TO post_comments_pkey
Now, when I checked the schema.... the table ID type had changed BACK to integer, instead of bigint.
Copying took about 3 days - so I am really, really hoping that I don't need to do this again. This is postgres10 on RDS.
EDIT
I'm going to take care of this problem like this:
Create a new table - call it my_table_bigint2.
Do this:
CREATE TABLE my_table_bigint2 (LIKE my_table INCLUDING ALL);
ALTER TABLE my_table_bigint2 ALTER id DROP DEFAULT;
ALTER TABLE my_table_bigint2 alter column id set data type bigint;
CREATE SEQUENCE my_table_bigint2_id_seq;
ALTER TABLE my_table_bigint2 ALTER id SET DEFAULT nextval('my_table_bigint2_id_seq');
ALTER SEQUENCE my_table_bigint2_id_seq OWNED BY my_table_bigint2.id;
And start populating that table with the new data. (This is fine given the usecase.)
In the meantime, I'm going to run
ALTER TABLE post_comments alter column id set data type bigint;
And finally, once that's done, I'm going to
INSERT INTO my_table SELECT * FROM my_table_bigint2;
My follow-up question - is this allowed? Will this create some interaction between the sequences? Should I use a new sequence?
I want to rename a table as part of a migration, but only if the table has not been renamed already. I'm currently running:
ALTER TABLE IF EXISTS old_name RENAME TO new_name
however, if new_name already exists it will still run. Is there a way to run this statement if and only if new_name does not exist?
You could always write an anonymous code block (or also a user defined function/procedure) similar to:
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_tables WHERE tablename = 'z') THEN
EXECUTE 'ALTER TABLE a RENAME TO z';
END IF;
END$$;
As far as I know you cannot specify it with the ALTER TABLE command directly.
Can I ALTER an existing table to be UNLOGGED?
PostgreSQL 9.5+ allows setting an existing table as LOGGED / UNLOGGED with the ALTER TABLE command... detailed better here.
For e.g.
ALTER TABLE table_test SET LOGGED;
ALTER TABLE table_test SET UNLOGGED;
The following solution is for PostgreSQL versions<=9.4:
You can do:
create unlogged table your_table_alt as
select * from your_table;
Then:
drop table your_table;
alter table your_table_alt rename to your_table;