for example i need to export mytbl as csv
CREATE TABLE public.mytbl
(
id integer,
product character varying(20),
patent character varying(50)
)
WITH (
OIDS = FALSE
)
;
and i use the following query to export the mytbl into csv
copy(select * from mytbl) to 'D:\mytbl.csv' with csv header
and using COPY mytbl FROM 'D:\mytbl.csv' CSV HEADER this will inserts from csv
but i need to delete the existing data in mytbl before importing it from mytbl.csv,
when i deletes getting error
ERROR: update or delete on table "mytbl" violates foreign key constraint "mytblX_forinkey_productid" on table "mytblX"
how to overcome this ?
On PostgreSQL 9.2
It appears that your mytblX has a FK to mytbl. Before you can drop your mytbl you should ALTER TABLE mytblX DROP CONSTRAINT mytblX_forinkey_productid. Then you can copy the data back in and issue ALTER TABLE mytblX ADD your_table_constraint.
Note that FK constraints are based on an index so you should create the appropriate index on the newly copied in data before you recreate the FK constraint. Also note that the new data may not meet the requirements set by mytblX data; i.e. if that references a productid which is not in the data you copy into the database then you will have problems that need to be solved first (usually manually and tediously).
You can set the constraint as deferrable, and then defer it. This will let you delete the contents of the original table and reload it from the file within a single transaction. But if the file doesn't contain all the rows it needs to satisfy the constraint, then you will get an error on COMMIT.
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"; ?
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 am relatively new to postgres (I am a django user - use pgsql via the orm), and I am trying to figure out a way to insert content into a specfic column - but so far, am not having any luck. So, I first have a database dzmodel_uf with two columns: id (which is the PK) and content - both of which are populated (say 50 entries).
Now, I would like to create another table, which references (foreign keys) to id of dzmodel_uf. So, I do the following:
--INITIALIZATION
CREATE TABLE MyNewTable(id integer REFERENCES dzmodel_uf (id));
ALTER TABLE ONLY FullTextSearch ADD CONSTRAINT mynewtable_pkey PRIMARY KEY (id);
which works fine. Now, I create a column on my MyNewTable table like so:
ALTER TABLE MyNewTable ADD COLUMN content_tsv_gin tsvector;
..which also works fine. Finally, I would like to add the content from dzmodel_uf - column content like so:
UPDATE MyNewTable SET content_tsv_gin = to_tsvector('public.wtf', dzmodel_uf(content) )
.. but this FAILS and says that column content does not exist..
In a nutshell, I am not sure how I can reference values from another table.
I hope I understood the question (it is rather fuzzy).There are no rows in the target table, so you have to add them.
You need INSERT, not UPDATE :
INSERT INTO MyNewTable (id,content_tsv_gin)
SELECT dzu.id, to_tsvector( public.wtf, dzu.content )
FROM dzmodel_uf dzu
;
I’d like to update some parameters for a table, such as the dist and sort key. In order to do so, I’ve renamed the old version of the table, and recreated the table with the new parameters (these can not be changed once a table has been created).
I need to preserve the id field from the old table, which is an IDENTITY field. If I try the following query however, I get an error:
insert into edw.my_table_new select * from edw.my_table_old;
ERROR: cannot set an identity column to a value [SQL State=0A000]
How can I keep the same id from the old table?
You can't INSERT data setting the IDENTITY columns, but you can load data from S3 using COPY command.
First you will need to create a dump of source table with UNLOAD.
Then simply use COPY with EXPLICIT_IDS parameter as described in Loading default column values:
If an IDENTITY column is included in the column list, the EXPLICIT_IDS
option must also be specified in the COPY command, or the COPY command
will fail. Similarly, if an IDENTITY column is omitted from the column
list, and the EXPLICIT_IDS option is specified, the COPY operation
will fail.
You can explicitly specify the columns, and ignore the identity column:
insert into existing_table (col1, col2) select col1, col2 from another_table;
Use ALTER TABLE APPEND twice, first time with IGNOREEXTRA and the second time with FILLTARGET.
If the target table contains columns that don't exist in the source
table, include FILLTARGET. The command fills the extra columns in the
source table with either the default column value or IDENTITY value,
if one was defined, or NULL.
It moves the columns from one table to another, extremely quickly; took me 4s for 1GB table in dc1.large node.
Appends rows to a target table by moving data from an existing source
table.
...
ALTER TABLE APPEND is usually much faster than a similar CREATE TABLE
AS or INSERT INTO operation because data is moved, not duplicated.
Faster and simpler than UNLOAD + COPY with EXPLICIT_IDS.