Postgres - CREATE FOREIGN TABLE based on other table - postgresql

I'm looking way to simplify CREATE FOREIGN command, so do need to specify all columns and types.
What I'm doing now (using file_fdw server):
CREATE FOREIGN TABLE temp_table_csv
(id integer, name text)
SERVER csv_log_server
OPTIONS ( filename 'path_to_file.csv', format 'csv');
What I would like to do:
CREATE FOREIGN TABLE temp_table_csv
(like example_table)
SERVER csv_log_server
OPTIONS ( filename 'path_to_file.csv', format 'csv');
Using LIKE or similar command so Postgres can read structure out of there
But it says "like is not supported"

Related

migrating to agensgraph create foreign table error

So, I'm taking a first look at migrating a PostgreSQL db to agensgraph db.
I'm using the manual https://bitnine.net/wp-content/uploads/2016/11/AgensGraph_Quick_Guide.pdf
first export as csv:
SET CLIENT_ENCODING TO 'utf8';
\COPY samples.samples TO
'C:\Users\garyn\Documents\graph_migration\pg_csv\samples_samples.csv'
WITH DELIMITER E'\t' CSV;
And on page 20 I follow the first steps, creating the foreign table:
CREATE EXTENSION file_fdw;
CREATE SERVER import_server FOREIGN DATA WRAPPER file_fdw;
CREATE FOREIGN TABLE vlabel_profile ( id graphid, properties text) SERVER import_server
OPTIONS( FORMAT 'csv', HEADER 'false',
FILENAME 'C:\Users\garyn\Documents\graph_migration\pg_csv\samples_samples.csv',
delimiter E'\t');
ERROR: cannot create table in graph schema
SQL state: XX000
Now, I haven't set any column names (as header=false) and I haven't changed the id graphid, properties text since the manual says it is setting up the table, but it states the file directory, any ideas how to get past this error? I'm back to being a noob.
The next steps will be:
CREATE FOREIGN TABLE elabel_profile ( id graphid, start graphid, "end" graphid, properties text) SERVER import_server OPTIONS( FORMAT 'csv', HEADER 'false', FILENAME '/path/file.csv', delimiter E'\t');
Then execute the import
CREATE VLABEL test_vlabel; LOAD FROM vlabel_profile AS profile_name CREATE (a:test_vlabel =row_to_json(profile_name)::jsonb);
CREATE ELABEL test_elabel; LOAD FROM elabel_profile AS profile_name MATCH (a:test_vlabel), (b:test_vlabel) WHERE (a).id::graphid = (profile_name).start AND (b).id::graphid = (profile_name).end CREATE (a)-[:test_elabel]->(b);
------------ UPDATE ------------
I'm now trying with the northwind dataset, again following the agens tutorial: https://bitnine.net/tutorial/english-tutorial.html
DROP GRAPH northwind CASCADE;
CREATE GRAPH northwind;
SET graph_path = northwind;
DROP SERVER northwind;
CREATE SERVER northwind FOREIGN DATA WRAPPER file_fdw;
CREATE FOREIGN TABLE categories (
CategoryID int,
CategoryName varchar(15),
Description text,
Picture bytea
)
SERVER northwind
OPTIONS (FORMAT 'csv', HEADER 'true', FILENAME 'D:\northwind\categories.csv', delimiter ',', quote '"', null '');
Same error
I have tried to create a foreign table with northwind dataset you mentioned but it works just fine for me as you see the below screen shot.
I installed the agensgraph and tried the sample with its latest version which is 2.1.0 since I didn't have agensgraph on my window OS.
If you let me know the version of agensgraph you are currently using and how you are accessing to agensgraph, I would be able to help you out more.
re: cannot create table in graph schema
This is an error you will get when your schema is the same as the name of a graph - or there is some other problem related to the default schema.
The default schema is called public. To check your current schema enter
select current_schema();
If it's not public you can set it with
set schema public;
then try to create a table
create table mytable(id int);

Is possible to use STDIN with CREATE FOREIGN TABLE?

I was looking for the STDIN option, to use FOREIGN TABLE in similar way as COPY... And discovery a "bug" in the Guide: there are no documentation about options at official sql-create-foreign-table Guide. No link, nothing:
OPTIONS ( option 'value' [, ...] )
Options to be associated with the new foreign table or one of its columns. ...
So, to lack of information transformed this question in two:
It is possible to use STDIN with FOREIGN TABLE?
Where the "OPTIONS" documentation?
edit to add example
CREATE FOREIGN TABLE t1 (
aa text,
bb bigint
) SERVER files OPTIONS (
filename '/tmp/bigBigdata.csv',
format 'csv',
header 'true'
;
Is a classic ugly PostgreSQL limitation on use filesystem, so I need a terminal solution ... Imagine on shell something with pipes, as
psql -c "ALTER FOREIGN TABLE t1 ... STDIN; CREATE TABLE t2 AS SELECT trim(aa) as aa, bb+1 as bb FROM t WHERE bb>999" < /thePath/bigBigdata.csv
Is a kind of "no direct copy, only filtering a stream of data", and creating a final table t2 from this filtered stream.
I think you are confused about foreign tables, I'll try to explain.
The data of a foreign table do not reside in PostgreSQL, but in an external data source (a file, a different database, etc.).
The foreign table is just a way to access these data from PostgreSQL as if they were a PostgreSQL table.
You can COPY to a foreign table FROM STDIN if the foreign data wrapper supports it, but that has nothing to with CREATE FOREIGN TABLE. CREATE FOREIGN TABLE defines how PostgreSQL should locate the external data and what the format of the data is.
There is no documentation of the options in CREATE FOREIGN TABLE because they depend on the foreign data wrapper you are using.
Look at the documentation of the foreign data wrapper.
Your example makes clear that what you need is not a foreign table, but a temporary table into which you can COPY the raw data which you later want to modify. You cannot use file_fdw for data that resides on the client machine.

Logging records in a postgresql database

I am having trouble thinking of a way to copy three fields out of a database into and append them to another table along with the current date. Basically what I want to do is:
DB-A: ID (N9), Name (C69), Phone (N15) {and a list of other fields I dont care about}
DB-B: Date (Todays date/time), Nane, Address, Phone (as above)
Would be great is this was a trigger in the DB on add or update of DB-A.
Greg
Quick and dirty using postgres_fdw
CREATE EXTENSION IF NOT EXISTS postgres_fdw ;
CREATE SERVER extern_server FOREIGN DATA WRAPPER postgres_fdw OPTIONS (host 'foreignserver.co.uk', port '5432', dbname 'mydb');
CREATE USER MAPPING FOR myuser SERVER extern_server OPTIONS (user 'anotheruser');
-- Creating a foreign table based on table t1 at the server described above
CREATE FOREIGN TABLE foreign_t1 (
dba INT,
name VARCHAR(9),
phone VARCHAR(15)
)
SERVER extern_server OPTIONS (schema_name 'public', table_name 't1');
--Inserting data to a new table + date
INSERT INTO t2 SELECT dba,name,phone,CURRENT_DATE FROM foreign_t1;
-- Or just retrieving what you need placing the current date as a column
SELECT dba,name,phone,CURRENT_DATE FROM foreign_t1;

Query to foreign table impossible due to index on custom stored function value in host database

I have a following situation.
In database A on server I, let's call it Host DB, there is a table, that has a following sample create script:
CREATE TABLE public.some_table (
id SERIAL PRIMARY KEY,
some_field TEXT
);
CREATE INDEX public.some_field_index
ON public.some_table USING btree
(my_custom_function(some_field));
As you can see, the index is created on a result of some custom, stored in database A, function my_custom_function.
Now I want to declare some_table as foreign table on other server, in database B. After creating the server, user mappings etc. I declare foreign table as:
CREATE FOREIGN TABLE public.some_table (
id SERIAL PRIMARY KEY,
some_field TEXT
)
SERVER host_server
OPTIONS (
schema_name 'public',
table_name 'some_table'
);
The table is created nicely, however I cannot query it. Instead I am getting following error:
ERROR: function my_custom_function(text) does not exist.
No function matches the given name and argument type.
You might need to add explcit type casts.
CONTEXT: Remote SQL command: SELECT id, some_field FROM public.some_table
SQL fuction my_custom_function during inlining.
I believe the problem is related to function my_custom_function not being declared on the server B, in the "guest" database. For some reasons i don't want to create this function. Is there any solution to overcome this problem?
Thanks for all your answers in advance.

CREATE TABLE AS with PRIMARY KEY in one statement (PostgreSQL)

Is there a way to set the PRIMARY KEY in a single "CREATE TABLE AS" statement?
Example - I would like the following to be written in 1 statement rather than 2:
CREATE TABLE "new_table_name" AS SELECT a.uniquekey, a.some_value + b.some_value FROM "table_a" AS a, "table_b" AS b WHERE a.uniquekey=b.uniquekey;
ALTER TABLE "new_table_name" ADD PRIMARY KEY (uniquekey);
Is there a better way of doing this in general (assume there are more than 2 tables, e.g. 10)?
According to the manual: create table and create table as you can either:
create table with primary key first, and use select into later
create table as first, and use add primary key later
But not both create table as with primary key - what you wanted.
If you want to create a new table with the same table structure of another table, you can do this in one statement (both creating a new table and setting the primary key) like this:
CREATE TABLE mytable_clone (
LIKE mytable
INCLUDING defaults
INCLUDING constraints
INCLUDING indexes
);
No, there is no shorter way to create the table and the primary key.
See the command below, it will create a new table with all the constraints and with no data. Worked in postgres 9.5
CREATE TABLE IF NOT EXISTS <ClonedTableName>(like <OriginalTableName> including all)
well in mysql ,both is possible in one command
the command is
create table new_tbl (PRIMARY KEY(`id`)) as select * from old_tbl;
where id is column with primary key of old_tbl
done...
You may do this way
CREATE TABLE IOT (EMPID,ID,Name, CONSTRAINT PK PRIMARY KEY( ID,EMPID))
ORGANIZATION INDEX NOLOGGING COMPRESS 1 PARALLEL 4
AS SELECT 1 as empid,2 id,'XYZ' Name FROM dual;