I'm using powerdesigner 15.2 to model an postgresql database, but i can't associate sequences with PKs...
read on internet that:
"To associate the sequence with the column, double-click the column entry. Then, in the General tab, specify the name of the sequence."
but i already did this...
the problem is that when i generate database, the sequences are simply created, but not associated with the column...
create sequence SQ_CARGO;
create table CARGO (
ID INT4 not null,
NOME VARCHAR(20) not null,
ROLE VARCHAR(100) not null,
constraint PK_CARGO primary key (ID)
);
Current DBMS in Powerdesigner: PostgreSQL 8 (but i'm using postgresql 9.4)
anyone knows how to do this? or else i will be forced to set this manually for each table:
ALTER TABLE cargo ALTER COLUMN ID SET DEFAULT NEXTVAL('SQ_CARGO'::regclass);
To resolve this, i wrote this code and replace, in DBMS Properties, the value:(Script->Objects->Table->Create).
create [%Temporary% ]table [%QUALIFIER%]%TABLE% ( %TABLDEFN% )
[%OPTIONS%];
.foreach_item(Columns)
.if (%COLNNO%==1) && (%Primary% == TRUE) && (%SQNC% != "")
ALTER TABLE [%QUALIFIER%]%TABLE% ALTER COLUMN %COLUMN% SET DEFAULT
nextval('[%QUALIFIER%]%SQNC%')
.endif
.next(\n)
Taking advantage, I have a problem when it generated the creation of code SEQUENCE.
I can not get the code to be generated with the OWNER of the prefix object.
ex:
The code is generated as follows:
CREATE SEQUENCE TABLE_SQ;
And it should be generated like this:
CREATE SEQUENCE OWNER.TABLE_SQ;
#Gilvan: You must select the owner on the "New Sequence" window, on the "Owner" combobox.
was a bug!
download a new version and works fine.
Related
Say we have a schema named : "test", a table in it as below:
CREATE TABLE IF NOT EXISTS test.details
(
id integer NOT NULL DEFAULT nextval('test.details_id_seq'::regclass),
username character varying(50) COLLATE pg_catalog."default" NOT NULL
)
as we could see id column is a Sequence which is already been created in this schema.
now if we create a new schema named "check" and altered details table schema as
create schema check
alter table test.details set schema check
will the sequence be auto created in check schema?
The sequence is an independent database object. If you change the schema of the table, the sequence will remain in the old schema, and the table will continue to use it. You can use ALTER SEQUENCE to change the sequence's schema as well, and the default value will continue to work (PostgreSQL stores the parsed default expression rather than the text).
All that becomes easier if you use identity columns to generate keys: there, you don't have to take care of the sequence. It is created automatically and changes schema with the table.
I am new in PostgreSQL and I am working with this database.
I got a file which I imported, and I am trying to get rows with a certain ID. But the ID is not defined, as you can see it in this picture:
so how do I access this ID? I want to use an SQL command like this:
SELECT * from table_name WHERE ID = 1;
If any order of rows is ok for you, just add a row number according to the current arbitrary sort order:
CREATE SEQUENCE tbl_tbl_id_seq;
ALTER TABLE tbl ADD COLUMN tbl_id integer DEFAULT nextval('tbl_tbl_id_seq');
The new default value is filled in automatically in the process. You might want to run VACUUM FULL ANALYZE tbl to remove bloat and update statistics for the query planner afterwards. And possibly make the column your new PRIMARY KEY ...
To make it a fully fledged serial column:
ALTER SEQUENCE tbl_tbl_id_seq OWNED BY tbl.tbl_id;
See:
Creating a PostgreSQL sequence to a field (which is not the ID of the record)
What you see are just row numbers that pgAdmin displays, they are not really stored in the database.
If you want an artificial numeric primary key for the table, you'll have to create it explicitly.
For example:
CREATE TABLE mydata (
id integer GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
obec text NOT NULL,
datum timestamp with time zone NOT NULL,
...
);
Then to copy the data from a CSV file, you would run
COPY mydata (obec, datum, ...) FROM '/path/to/csvfile' (FORMAT 'csv');
Then the id column is automatically filled.
I have a table with existing data. Is there a way to add a primary key without deleting and re-creating the table?
(Updated - Thanks to the people who commented)
Modern Versions of PostgreSQL
Suppose you have a table named test1, to which you want to add an auto-incrementing, primary-key id (surrogate) column. The following command should be sufficient in recent versions of PostgreSQL:
ALTER TABLE test1 ADD COLUMN id SERIAL PRIMARY KEY;
Older Versions of PostgreSQL
In old versions of PostgreSQL (prior to 8.x?) you had to do all the dirty work. The following sequence of commands should do the trick:
ALTER TABLE test1 ADD COLUMN id INTEGER;
CREATE SEQUENCE test_id_seq OWNED BY test1.id;
ALTER TABLE test1 ALTER COLUMN id SET DEFAULT nextval('test_id_seq');
UPDATE test1 SET id = nextval('test_id_seq');
Again, in recent versions of Postgres this is roughly equivalent to the single command above.
ALTER TABLE test1 ADD COLUMN id SERIAL PRIMARY KEY;
This is all you need to:
Add the id column
Populate it with a sequence from 1 to count(*).
Set it as primary key / not null.
Credit is given to #resnyanskiy who gave this answer in a comment.
To use an identity column in v10,
ALTER TABLE test
ADD COLUMN id { int | bigint | smallint}
GENERATED { BY DEFAULT | ALWAYS } AS IDENTITY PRIMARY KEY;
For an explanation of identity columns, see https://blog.2ndquadrant.com/postgresql-10-identity-columns/.
For the difference between GENERATED BY DEFAULT and GENERATED ALWAYS, see https://www.cybertec-postgresql.com/en/sequences-gains-and-pitfalls/.
For altering the sequence, see https://popsql.io/learn-sql/postgresql/how-to-alter-sequence-in-postgresql/.
I landed here because I was looking for something like that too. In my case, I was copying the data from a set of staging tables with many columns into one table while also assigning row ids to the target table. Here is a variant of the above approaches that I used.
I added the serial column at the end of my target table. That way I don't have to have a placeholder for it in the Insert statement. Then a simple select * into the target table auto populated this column. Here are the two SQL statements that I used on PostgreSQL 9.6.4.
ALTER TABLE target ADD COLUMN some_column SERIAL;
INSERT INTO target SELECT * from source;
ALTER TABLE test1 ADD id int8 NOT NULL GENERATED ALWAYS AS IDENTITY;
I'm using DBeaver to migrate data from Postgres to Derby. When I use the wizard in DBeaver to go directly from one table to another, the primary key in Derby is being generated instead of inserted. This causes issues on foreign keys for subsequent tables.
If I generate the SQL, the primary key is part of the SQL statement and is properly inserted. However there are too many rows to handle in this way.
Is there a way to have DBeaver insert the primary key instead of letting it be generated when importing / exporting directly to database tables?
Schema of target table
CREATE TABLE APP.THREE_PHASE_MOTOR (
ID BIGINT NOT NULL DEFAULT GENERATED_BY_DEFAULT,
VERSION INTEGER NOT NULL,
CONSTRAINT SQL130812103636700 PRIMARY KEY (ID)
);
CREATE INDEX SQL160416184259290 ON APP.THREE_PHASE_MOTOR (ID);
Schema of source table
CREATE TABLE public.three_phase_motor (
id int8 NOT NULL DEFAULT nextval('three_phase_motor_id_seq'::regclass),
"version" int4 NOT NULL,
CONSTRAINT three_phase_motor_pkey PRIMARY KEY (id)
)
WITH (
OIDS=FALSE
);
I found a trick working with version 6.0.5; do these steps:
double click a table name
then select Data tab
then click the gray table corner (the one on top of row order numbers) in order to select all rows
then right click the same gray table corner
then select Generate SQL -> INSERT menu
a window with the INSERT instructions including id (primary key) will popup.
PS: when selecting a subset of rows the same menu would work for only those too
When you go to export, check the Include generated column option, and the primary key (auto-incremented) will be included in the export.
See this for more details: https://github.com/dbeaver/dbeaver/commit/d1f74ec88183d78c7c6620690ced217a52555262
Personally I think this needs to be more clear, and why they excluded it in the first place was not good data integrity.
As of now DBeaver version [22.0.5] you have to select Include generated columns as true, as shown in the following screenshot that will export the primary/generated columns.
I'm using Grails 3.0.7 and Postgres 9.2. I'm very new to Postgres, so this may be a dumb question. How do I correctly associate an id generator sequence with a table? I read somewhere that if you create a table with an id column that has a serial datatype, then it will automatically create a sequence for that table.
However, the column seems to be created with a type of bigint. How do I get Grails to create the column with a bigserial datatype, and will this even solve my problem? What if I want one sequence per table? I'm just not sure how to go about setting this up because I've never really used Postgres in the past.
You can define a generator in a domain class like this:
static mapping = {
id generator:'sequence', params:[sequence:'domain_sq']
}
If the sequence is already present in the database then you'll need to name it in the params.
There are other properties also available as outlined in the documentation, for example:
static mapping = {
id column: 'book_id', type: 'integer'
}
In Postgres 10 or later consider an IDENTITY column instead. See:
Auto increment table column
However, the column seems to be created with a type of bigint. How do
I get Grails to create the column with a bigserial datatype, and will
this even solve my problem?
That's expected behavior. Define the column as bigserial, that's all you have to do. The Postgres pseudo data types smallserial, serial and bigserial create a smallint, int or bigint column respectively, and attach a dedicated sequence. The manual:
The data types smallserial, serial and bigserial are not true types,
but merely a notational convenience for creating unique identifier
columns (similar to the AUTO_INCREMENT property supported by some
other databases). In the current implementation, specifying:
CREATE TABLE tablename (
colname SERIAL
);
is equivalent to specifying:
CREATE SEQUENCE tablename_colname_seq;
CREATE TABLE tablename (
colname integer NOT NULL DEFAULT nextval('tablename_colname_seq')
);
ALTER SEQUENCE tablename_colname_seq OWNED BY tablename.colname;
Big quote, I couldn't describe it any better than the manual.
Related:
Get table and column "owning" a sequence
Safely rename tables using serial primary key columns