Postgres: foreign key to foreign table - postgresql-9.4

I have a foreign table, for example:
CREATE FOREIGN TABLE film (
id varchar(40) NOT NULL,
title varchar(40) NOT NULL,
did integer NOT NULL,
date_prod date,
kind varchar(10),
len interval hour to minute
)
SERVER film_server;
with id as the primary key for that table (set in the remote database). I would like to have a local table reference the foreign table, and set a foreign key constraint on the local table -- for example:
CREATE TABLE actor (
id varchar(40) NOT NULL,
name varchar(40) NOT NULL,
film_id varchar(40) NOT NULL,
)
ALTER TABLE actor ADD CONSTRAINT actor_film_fkey FOREIGN KEY (film_id)
REFERENCES film(id);
However, when I try to add the foreign key constraint, I get the error:
ERROR: referenced relation "film" is not a table
Is it possible to add a foreign key constraint to a foreign table?

It's no possible create index on foreign tables.
CREATE INDEX idx_film ON film (id);
This is the error:
ERROR: cannot create index on foreign table

Related

Trying to make a UNIQUE KEY become a FOREIGN KEY, but it says error

I created this table. I want the user_id to be inserted without someone having to type it. Can someone help me? When I tried to create it it shows this error:
Why is the fk_id being compared to cpf?
CREATE TABLE code.went_to
(
user_id INTEGER,
cpf VARCHAR(11) NOT NULL,
cep VARCHAR(8) NOT NULL,
date DATE,
contact_id INTEGER,
CONSTRAINT fk_id
FOREIGN KEY (user_id) REFERENCES code.user,
CONSTRAINT fk_cpf_user
FOREIGN KEY (cpf) REFERENCES code.user,
CONSTRAINT fk_cep_place
FOREIGN KEY (cep) REFERENCES code.place,
CONSTRAINT fk_tipo_id
FOREIGN KEY (tipo_id) REFERENCES code.contact,
EXCLUDE USING gist (cpf WITH =, cep WITH =, daterange(data, (data + interval '4 months')::date) WITH &&),
EXCLUDE USING gist (cep WITH =, contact_id WITH =, daterange(data, (data + interval '1 months')::date) WITH &&)
);
The table that user_id comes from:
CREATE TABLE code.user
(
user_id SERIAL NOT NULL,
cpf VARCHAR(11) NOT NULL,
name CHAR(75) NOT NULL,
nick_name VARCHAR(15),
CONSTRAINT pk_cpf PRIMARY KEY(cpf),
CONSTRAINT un_id UNIQUE (id),
CONSTRAINT un_nick_name UNIQUE (nick_name)
);
Sorry if its stated weird, my English is not the best. But essentially the question should be:
How could I import data (user_id) from one table (user) into another table (went_to) based on the primary key (cpf)?
If you don't specify a target column, the references clause assumes the primary key of the target table. There is no matching on the name happening.
You need to include the column of the unique key in your foreign key definition:
CONSTRAINT fk_id FOREIGN KEY (user_id) REFERENCES code."user"(user_id)
To make things less confusing, I would also do that for the FK that references the PK
CONSTRAINT fk_cpf_user FOREIGN KEY (cpf) REFERENCES code."user"(cpf),

How to add foreign key in PostgreSQL

I created this first table named 'bookstore' where Primary Key is book_name:
create table bookstore (book_name varchar primary key, author varchar, price decimal);
I am trying to create a second table named 'name' where name is primary key. I want to make this primary key- author.name as a foreign key of bookstore.author.
create table author (name varchar primary key, place varchar,
constraint fk_author_bookstore foreign key(name) references bookstore(author));
But the error is: ERROR: there is no unique constraint matching given keys for referenced table "bookstore"
SQL state: 42830
I am new to SQL, so, hoping to get some help. If you can, please write the correct code.
Thanks
Name column in author table is primary key and it's referenced as foreign key in bookstore table.
-- PostgreSQL (v11)
create table author (name varchar primary key, place varchar);
create table bookstore (book_name varchar primary key, author varchar, price decimal
, CONSTRAINT fk_author_bookstore
FOREIGN KEY(author)
REFERENCES author(name));
Please check from url https://dbfiddle.uk/?rdbms=postgres_11&fiddle=8394f796433ed8bc170c2889286b3fc2
Add foreign key after table creation
-- PostgreSQL(v11)
ALTER TABLE bookstore
ADD CONSTRAINT fk_author_bookstore FOREIGN KEY (author)
REFERENCES author (name);
Please check from url https://dbfiddle.uk/?rdbms=postgres_11&fiddle=d93cf071bfd0e3940dfd256861be813c

How to use timescale hypertables with foreign keys and keep a one-to-many relation?

I am trying to create a database with minimum redundancy in mind. We would like to use the timescaledb hypertables (I run postgreSQL v. 12 and timescaledb v. 1.7.4). The postgreSQL code to create the tables are as follows - you can see the dbdiagram here https://dbdiagram.io/d/5f992f0e3a78976d7b797ca2 or view the tables here Image of database
CREATE TABLE "datapoints" (
"id" bigserial UNIQUE NOT NULL,
"tstz" timestamptz NOT NULL,
"entity_id" bigint NOT NULL,
"value" real NOT NULL,
PRIMARY KEY ("tstz", "entity_id")
);
CREATE TABLE "datapoint_quality" (
"tstz" timestamptz NOT NULL,
"datapoint_id" bigint NOT NULL,
"flag_id" bigint NOT NULL,
PRIMARY KEY ("tstz", "datapoint_id", "flag_id")
);
CREATE TABLE "quality_flags" (
"id" bigserial PRIMARY KEY,
"value" text
);
CREATE TABLE "sensor_types" (
"id" bigserial PRIMARY KEY,
"name" text UNIQUE NOT NULL
);
CREATE TABLE "sensors" (
"tstz" timestamptz NOT NULL DEFAULT (now()),
"id" bigserial UNIQUE NOT NULL,
"name" text NOT NULL,
"parent" bigint NOT NULL,
"type" bigint NOT NULL,
PRIMARY KEY ("tstz", "id")
);
CREATE TABLE "datapoint_annotation" (
"tstz" timestamptz NOT NULL,
"datapoint_id" bigint NOT NULL,
"annotation_id" bigint NOT NULL,
PRIMARY KEY ("tstz", "datapoint_id", "annotation_id")
);
CREATE TABLE "annotations" (
"id" bigserial PRIMARY KEY NOT NULL,
"value" text NOT NULL
);
ALTER TABLE "datapoints" ADD FOREIGN KEY ("entity_id") REFERENCES "sensors" ("id");
ALTER TABLE "datapoint_quality" ADD FOREIGN KEY ("datapoint_id") REFERENCES "datapoints" ("id");
ALTER TABLE "datapoint_quality" ADD FOREIGN KEY ("flag_id") REFERENCES "quality_flags" ("id");
ALTER TABLE "sensors" ADD FOREIGN KEY ("parent") REFERENCES "sensors" ("id");
ALTER TABLE "sensors" ADD FOREIGN KEY ("type") REFERENCES "sensor_types" ("id");
ALTER TABLE "datapoint_annotation" ADD FOREIGN KEY ("datapoint_id") REFERENCES "datapoints" ("id");
ALTER TABLE "datapoint_annotation" ADD FOREIGN KEY ("annotation_id") REFERENCES "annotations" ("id");
CREATE UNIQUE INDEX ON "quality_flags" ("value");
CREATE UNIQUE INDEX ON "annotations" ("value");
So far so good - next I want to create the hypertables, which I do as:
SELECT create_hypertable('datapoint_annotation', 'tstz');
SELECT create_hypertable('datapoint_quality', 'tstz');
SELECT create_hypertable('datapoints', 'tstz');
SELECT create_hypertable('sensors', 'tstz');
This works well for the first two lines, but for the latter two I get the following error:
ERROR: cannot create a unique index without the column "tstz" (used in partitioning)
SQL state: TS103
I can include the tstz in the primary key as ("id", "tstz") and use that as foreign key, but this gives me a one-to-one relation, and for minimum redundancy I would like to have a one-to-many relation.
I am sure there should be some way to do this - so what am I missing?
I'll take the foreign key constraint from datapoint_quality to datapoints as an example.
To make that work with a partitioned table, you need a unique constraint on datapoint. As the error message tell you, such a constraint must contain the partitioning key. So you end up with
ALTER TABLE datapoints ADD UNIQUE (id, tstz);
To reference that unique constraint from datapoint_quality, you need to have the timestamp there too:
ALTER TABLE datapoint_quality ADD datapoints_tstz timestamp with time zone;
You have to fill it with the appropriate values:
UPDATE datapoint_quality AS dq
SET datapoints_tstz = d.tstz
FROM datapoints AS d
WHERE d.id = dq.datapoint_id;
Then set it NOT NULL:
ALTER TABLE datapoint_quality ALTER datapoints_tstz SET NOT NULL;
Now you can define your foreign key:
ALTER TABLE datapoint_quality
ADD FOREIGN KEY (datapoint_id, datapoints_tstz)
REFERENCES datapoints (id, tstz) MATCH FULL;
There is no other way to have foreign key constraints with partitioned tables.
After testing the proposed solution by Laurenz in a database I have and also after replicating the original database of this case. I use PostgreSQL 12.6 and timescaledb 1.7.5.
Basically, I arrived well until defining the Foreign Key for Table datapoint_quality:
ALTER TABLE datapoint_quality
ADD FOREIGN KEY (datapoint_id, datapoints_tstz)
REFERENCES datapoints (id, tstz) MATCH FULL;
The next error is present in both databases I've tested after several attempts (included above one) to define the foreign key to a hypertable:
ERROR: foreign keys to hypertables are not supported Blockquote SQL state: 0A000
According to https://docs.timescale.com/timescaledb/latest/overview/limitations/##distributed-hypertable-limitations, it looks like the above error is part of the hypertable limitations:
Foreign key constraints referencing a hypertable are not supported.
Considering this, does anyone know any solution at the DB level to establish the relationships (1..* or ...) among a table without hypertables to other tables with hypertables behind?
Maybe could be a solution to deal with this at even a REST API level (e.g. Django or Flask) given at timescaledb or PostgreSQL I have not found much more solutions.

Postgresql [42P01] ERROR while creating foreign key

I want to create a foreign key in my postgresql db table but i'm receiving still message about non existing table (???!!?) It's driving me crazy because I have created necessary relation (address).
CREATE TABLE base_schema.station
(
id SERIAL PRIMARY KEY NOT NULL,
phone VARCHAR(20) NOT NULL,
station_address INT NOT NULL,
CONSTRAINT station_address_id_fk FOREIGN KEY (station_address)
REFERENCES address (id)
);
CREATE UNIQUE INDEX station_id_uindex ON base_schema.station (id);
I'm using jetbrains datagrip
Thanks in advance

Postgresql sharding with citus extension not working

I am using Postgresql with citus extension for sharding and unable to shard tables like below.
Below table has a primary key and 2 unique keys. I am trying to shard against column with primary key i.e pid.
Note: I am not allowed to change the table structure. These tables are created by tool.
CREATE TABLE person
(
pid bigint NOT NULL,
name character varying(100),
address_pid bigint NOT NULL,
address_type character varying(100),
CONSTRAINT id_pkey PRIMARY KEY (pid),
CONSTRAINT addr_id UNIQUE (address_pid),
CONSTRAINT addr_type_id UNIQUE (address_type, address_pid)
);
This my sharding query:
select create_distributed_table('person', 'pid');
Error it throw is:
Error: Distributed relations cannot have UNIQUE, EXCLUDE, or PRIMARY KEY constraints that do not include the partition column
Can anyone help me with sharding these kind of tables?
#CraigKerstiens Addition to this question:
How to handle sharding when we have multiple foreign keys like this one.
CREATE TABLE table
(
pid bigint NOT NULL,
search_order integer NOT NULL,
resource_pid bigint NOT NULL,
search_pid bigint NOT NULL,
CONSTRAINT hfj_search_result_pkey PRIMARY KEY (pid),
CONSTRAINT idx_searchres_order UNIQUE (search_pid, search_order),
CONSTRAINT fk_searchres_res FOREIGN KEY (resource_pid)
REFERENCES public.table1 (res_id) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE NO ACTION,
CONSTRAINT fk_searchres_search FOREIGN KEY (search_pid)
REFERENCES public.table2 (pid) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE NO ACTION
)
Assuming that table1 and table2 are already sharded.
Within Citus at this time you cannot have a unique constraint that doesn't include they column you are partitioning on. In this case, it'd be possible to enforce addresses were unique to the person id, but not globally unique. To do that you could:
CREATE TABLE person
(
pid bigint NOT NULL,
name character varying(100),
address_pid bigint NOT NULL,
address_type character varying(100),
CONSTRAINT id_pkey PRIMARY KEY (pid),
CONSTRAINT addr_id UNIQUE (pid, address_pid),
CONSTRAINT addr_type_id UNIQUE (pid, address_type, address_pid)
);