I am trying to add an identity column in a table through alter query using Ingres DB. While creating the table, i am able to define the identity column but not when i am trying to add it through alter query. Kindly Suggest me an alter query for it.
It's not as straightforward as you might think, "alter table" has a a number of restrictions which make this a multi-step operation. Try this:
create table something(a integer, b varchar(20)) with page_size=8192;
alter table something add column c integer not null with default;
modify something to reconstruct;
alter table something alter column c integer not null generated always as identity;
modify something to reconstruct;
Related
I need to add new column on my table would be uuid data type, here my code:
ALTER TABLE core.example add COLUMN newcolumn SET DATA TYPE UUID USING (uuid_generate_v4())
but show me this error:
ERROR: type modifier is not allowed for type "uuid"
LINE 1: ALTER TABLE core.example add COLUMN newsi UUID (uuid_genera...
I dont want to alter a column, would be to create a new column on my table. Any idea how to make this?
Regards
When adding a new column you don't use SET DATA TYPE. Your statement should look like:
ALTER TABLE core.example ADD COLUMN newcolumn UUID DEFAULT (uuid_generate_v4());
The DEFAULT clause will immediately fill the column with UUIDs.
Alternatively if you you just want to fill the column with initial data, you can drop the DEFAULT clause afterward:
ALTER TABLE core.example ALTER COLUMN newcolumn DROP DEFAULT;
Note that if you are using Postgres 13 and newer it is generally preferrable to use gen_random_uuid() since that method is built-in and does not rely on the uuid-ossp extension.
I'm writing a database migration that adds a new table whose id column is populated using uuid_generate_v4(). However, that generated id needs to be used in an UPDATE on another table to associate the entities. Here's an example:
BEGIN;
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE TABLE IF NOT EXISTS models(
id,
type
);
INSERT INTO models(id)
SELECT
uuid_generate_v4() AS id
,t.type
FROM body_types AS t WHERE t.type != "foo";
ALTER TABLE body_types
ADD COLUMN IF NOT EXISTS model_id uuid NOT NULL DEFAULT uuid_generate_v4();
UPDATE TABLE body_types SET model_id =
(SELECT ....??? I'M STUCK RIGHT HERE)
This is obviously a contrived query with flaws, but I'm trying to illustrate that what it looks like I need is a way to store the uuid_generate_v4() value from each inserted row into a variable or hash that I can reference in the later UPDATE statement.
Maybe I've modeled the solution wrong & there's a better way? Maybe there's a postgresql feature I just don't know about? Any pointers greatly appreciated.
I was modeling the solution incorrectly. The short answer is "don't make the id in the INSERT random". In this case the key is to add the 'model_id' column to 'body_types' first. Then I can use it in the INSERT...SELECT without having to save it for later use because I'll be selecting it from the body_types table.
BEGIN;
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
ALTER TABLE body_types
ADD COLUMN IF NOT EXISTS model_id uuid NOT NULL DEFAULT uuid_generate_v4();
CREATE TABLE IF NOT EXISTS models(
id,
type
);
INSERT INTO models(id)
SELECT
t.model_id AS id
,t.type
FROM body_types AS t WHERE t.type != "foo";
Wish I had a better contrived example, but the point is, avoid using random values that you have to use later, and in this case it was totally unnecessary to do so anyway.
I create table in PostgreSQL but I forgot to add auto increment.
How to alter empty Id column in Postgres to add auto increment?
Starting with Postgres 10 it's recommended to use identity columns for this.
You can turn an existing column into an identity column using an ALTER TABLE:
alter table the_table
alter id add generated always as identity;
If you already have data in the table, you will need to sync the sequence:
select setval(pg_get_serial_sequence('the_table', 'id'), (select max(id) from the_table));
You will need to create a sequence owned by that column and set that as the default value.
e.g.
CREATE TABLE mytable (id int);
CREATE SEQUENCE mytable_id_seq OWNED BY mytable.id;
ALTER TABLE mytable ALTER COLUMN id SET DEFAULT nextval('mytable_id_seq');
In database dump created with pg_dump, some tables have DEFAULTs in the CREATE TABLE statement, i.e.:
CREATE TABLE test (
f1 integer DEFAULT nextval('test_f1_seq'::regclass) NOT NULL
);
But others have an additional ALTER statement:
ALTER TABLE ONLY test2 ALTER COLUMN f1 SET DEFAULT nextval('test2_f1_seq'::regclass);
What is the reason of this? All sequential fields were created with type SERIAL, but in the dump they look different, and I can't guess any rule for this.
The difference must be that in the first case, the sequence is “owned” by the table column.
You can specify this dependency using the OWNED BY clause when you create a sequence. A sequence that is owned by a column will automatically be dropped when the column is.
If a sequence is implicitly created by using serial, it will be owned by the column.
I have a column where I want to change the data type. I currently am using Redshift. I know I can use the alter table statement to change the datatype, but this would change the order of the columns.
Is there a way to change the datatype without changing the order of the column?
I would recommend creating a new table with the schema you want and copying it over from the old table using a insert into new_table (select * from old_table) statement (here you can also do any casting to the new data type), after which you can drop the old table and rename the new one:
drop table old_table;
alter table new_table rename to old_table;
Using ALTER TABLE table_name ALTER COLUMN column_name TYPE new_data_type will not change the order of the columns in your table.
Please note that this clause can only changes the size of a column defined as a VARCHAR data type.
There are also other limitations described in AWS documentation of ALTER TABLE