Postgresql [42P01] ERROR while creating foreign key - postgresql

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

Related

postgresql, key is not present in table error, but key present in the table

I have tables providers, and provider_groups.
providers:
create table providers
(
id integer not null constraint providers_pkey primary key,
available boolean not null,
);
and provider_groups
create table provider_groups
(
id integer not null provider_groups_pkey primary key,
provider_id integer not null constraint fk_237d25c5d3e1ebb8
references providers on delete cascade,
type varchar(100) not null
);
create index idx_237d25c5d3e1ebb8
on provider_groups (provider_id);
and my application (which using of doctrine ORM) trying to update data for some provider and his related group. I'm sure both provider and group exists in database, but for some reason it's failing with error
SQLSTATE[23503]: Foreign key violation: 7 ERROR: insert or update on table "provider_groups" violates foreign key constraint "fk_237d25c5d3e1ebb8"\n
DETAIL: Key (provider_id)=(28007) is not present in table "providers".
but as I mentioned it's there, I can see it through database UI.
What I'm doing wrong??? Can it be related to some cache on DB side, as it's a pretty old logic running for a while and that error apears only now... Thanks in advice!

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 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)
);

Postgres: foreign key to foreign table

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