Postgres Datebase multi foreign keys - postgresql

I have a table described as following:
Table "public.lead"
Column | Type | Modifiers
-----------------------------+--------------------------------+-----------------------------------------
id | character varying(36) | not null
reference_code | character varying(20) | not null
country_id | character varying(36) | not null
language_id | character varying(36) | not null
locale_id | character varying(36) | not null
from_country_id | character varying(36) | not null
to_country_id | character varying(36) | not null
customer_id | character varying(36) | not null
user_id | character varying(36) |
from_date | date | not null
from_date_type | smallint | not null default (0)::smallint
from_street | character varying(200) |
from_postalcode | character varying(25) |
from_city | character varying(100) |
from_country | character varying(50) |
from_apartment_type | character varying(255) | not null default '0'::character varying
from_floor | smallint |
from_rooms | numeric(3,1) |
from_people | integer |
from_squaremeter | integer |
from_elevator | smallint | not null
I am trying to create foreign keys for (country_id, from_country_id, to_country_id)
As you can see all these 3 fields has a relation with table.
But when i try to create these foreign keys, i got the following error.
ERROR: insert or update on table "lead" violates foreign key constraint "lead_to_country_id" Detail: Key (to_country_id)=(United Kingdom) is not present in table "country".
Details

This error is often related to a missing key.
When you try to create a foreign key AFTER an insert statement, SQL searches for those keys in the table which has the Primary Key (PK).
Eg.
table_with_PK
col1(Pk) | col2| coln ...
id_1 foo bar ...
id_2 nan ana ...
table_connected_to_table_with_PK
col1(Fk) | col2 | etc...
id_1
id_2
id_3 (Error because not present in table_with_PK)
So first create the table which has your primary keys, then populate it.
Second create the table with foreign keys, make foreign keys(Fk), then populate/update it, in order to have coherence in your database.
Check postgresql documentation on constraints: https://www.postgresql.org/docs/current/static/ddl-constraints.html

The error message pretty much says it: You are trying to set the to_country_id column value to 'United Kingdom' which does not exist in the referenced country table. Insert that value into the country table and retry.

Related

How to migrate tables with defaults, constraints and sequences with AWS DMS for postgres to postgres migration?

I recently did a migration from a RDS postgresql to Aurora postgresql. The tables were migrated successfully but the tables are missing their defaults, constraints and references. It also did not migrate any sequences.
Table in source database:
Table "public.addons_snack"
Column | Type | Collation | Nullable | Default
---------------+--------------------------+-----------+----------+------------------------------------------
id | integer | | not null | nextval('addons_snack_id_seq'::regclass)
name | character varying(100) | | not null |
snack_type | character varying(2) | | not null |
price | integer | | not null |
created | timestamp with time zone | | not null |
modified | timestamp with time zone | | not null |
date | date | | |
Indexes:
"addons_snack_pkey" PRIMARY KEY, btree (id)
Check constraints:
"addons_snack_price_check" CHECK (price >= 0)
Referenced by:
TABLE "addons_snackreservation" CONSTRAINT "addons_snackreservation_snack_id_373507cf_fk_addons_snack_id" FOREIGN KEY (snack_id) REFERENCES addons_snack(id) DEFERRABLE INITIALLY DEFERRED
Tables in target database
Table "public.addons_snack"
Column | Type | Collation | Nullable | Default
---------------+-----------------------------+-----------+----------+---------
id | integer | | not null |
name | character varying(100) | | not null |
snack_type | character varying(2) | | not null |
price | integer | | not null |
created | timestamp(6) with time zone | | not null |
modified | timestamp(6) with time zone | | not null |
date | date | | |
Indexes:
"addons_snack_pkey" PRIMARY KEY, btree (id)
Did I do something wrong or DMS is not capable of doing this?
This SQL Snippet will be a clear answer for you.
You can restore Index and Constraint by using pg_dump and pg_restore, and the snippet consists of executing them.

Two Postgres tables with same column name and same Index name. Need to drop index on one of them

I have two tables:
x_development=# \d+ xref__email_addresses__organizations
Table "public.xref__email_addresses__organizations"
Column | Type | Modifiers | Storage | Stats target | Description
-------------------------+-----------------------------+------------------------+---------+--------------+-------------
email_address_id | integer | not null | plain | |
rorganization_id | integer | not null | plain | |
last_update | timestamp without time zone | not null default now() | plain | |
Indexes:
"email_address_id_idx" UNIQUE, btree (email_address_id)
"xref_idx" UNIQUE, btree (email_address_id, organization_id)
Foreign-key constraints:
"email_address_id_fkey" FOREIGN KEY (email_address_id) REFERENCES email_addresses(email_address_id) ON UPDATE CASCADE ON DELETE RESTRICT
"organization_id_fkey" FOREIGN KEY (realtor_organization_id) REFERENCES realtor_organizations(realtor_organization_id) ON UPDATE CASCADE ON DELETE RESTRICT
x_development=# \d+ email_addresses
Table "public.email_addresses"
Column | Type | Modifiers | Storage | Stats target | Description
--------------------+---------+----------------------------------------------------------------------------+----------+--------------+-------------
email_address_id | integer | not null default nextval('email_addresses_email_address_id_seq'::regclass) | plain | |
email_address | citext | not null | extended | |
unsubscribe_reason | text | not null default ''::text | extended | |
Indexes:
"email_addresses_pkey" PRIMARY KEY, btree (email_address_id)
"email_address_idx" UNIQUE, btree (email_address)
Referenced by:
TABLE "xref__email_addresses__organizations" CONSTRAINT "email_address_id_fkey" FOREIGN KEY (email_address_id) REFERENCES email_addresses(email_address_id) ON UPDATE CASCADE ON DELETE RESTRICT
Note they both have an email_address_id column and
"email_address_id_idx" UNIQUE, btree (email_address_id) index.
I need to drop the email_address_id_idx on the xref__email_addresses__organizations table but it seems if mis-created the table by having two identical index names.
How do I drop the email_address_id_idx from the xref__email_addresses__organizations table?
From what i have understood, the indexes are different. One of them is email_address_id_idx and the other is email_address_idx. So I Think you can just use drop index to remove the desired one.

Compound foreign key constraint with a String literal

I have a table with a compound primary key:
Table "account.enum"
Column | Type | Modifiers
-----------+------------------------+-----------
classname | character varying(256) | not null
name | character varying(64) | not null
active | boolean | not null
Indexes: "enum_pkey" PRIMARY KEY, btree (classname, name)
Values:
classname | name | active
--------------+--------+--------
CURRENCY | EUR | t
CURRENCY | USD | t
MUTATIONTYPE | CREDIT | t
MUTATIONTYPE | DEBET | t
Another table account uses this table:
Table "account.mutation"
Column | Type | Modifiers
-----------------+------------------------+-------------------------------------------------------
id | bigint | not null default nextval('mutation_id_seq'::regclass)
accountnumber | character varying(9) | not null
interestdate | date | not null
balancebefore | numeric(10,2) | not null
balanceafter | numeric(10,2) | not null
transactiondate | date | not null
amount | numeric(10,2) | not null
description | character varying(512) | not null
ordernumber | smallint | default (-1)
mutationtype | character varying(64) |
currency | character varying(64) |
I want to add foreign key constraints (for mutationtype and currency):
alter table mutation add constraint FK_mutationtype foreign key('MUTATIONTYPE', mutationtype) references enum(classname, name);
alter table mutation add constraint FK_currency foreign key('CURRENCY', currency) references enum(classname, name);
However the string literals are not accepted.
What am I doing wrong? Is what I want possible in postgres?
You cannot do this because foreign keys can only be defined on columns, not on expressions like the literal 'MUTATIONTYPE'.
You could introduce a column like mutation_class in mutation that is always set to 'MUTATIONTYPE', but that sounds wasteful, redundant and silly.
I think that you should solve the problem by having different lookup tables for the different enumerations, then the difficulty would just vanish, and the whole design looks more reasonable from a relational perspective.

Insert row into a postgresql table

I have the following table definition:
foo=# \d+ tag
Table "public.tag"
Column | Type | Modifiers | Storage | Stats target | Description
-------------+------------------------+--------------------------------------------------+----------+--------------+-------------
id | integer | not null default nextval('tag_id_seq'::regclass) | plain | |
name | character varying(255) | not null | extended | |
version | integer | not null | plain | |
description | character varying(255) | not null | extended | |
active | boolean | not null | plain | |
Indexes:
"tag_pkey" PRIMARY KEY, btree (id)
"unique_tag" UNIQUE CONSTRAINT, btree (name, version)
I am trying to insert a row into as follows:
foo=# insert into tag (name, version, description, active) values ("scala", 1, "programming language", true);
ERROR: column "scala" does not exist
LINE 1: ... tag (name, version, description, active) values ("scala", 1...
I took this command from the manual but it doesn't work. What I am doing wrong? It's a simple thing but I'm stumped. First time I am using postgres.
Postgres uses single quotes.
insert into tag (name, version, description, active) values ('scala', 1, 'programming language', true);

Error:"Key ... is not present in table"

I have a table with a character varying(12) field in it which is its PRIMARY KEY. I ran this query
SELECT * FROM bg WHERE bg_id ='470370111002'
It selects a row from the table. All looks good. Then I try.
INSERT INTO csapp_center_bgs(bg_id,center_id) VALUES('470370111002',2)
There is a foreign key on bg_id that looks like...
ALTER TABLE csapp_center_bgs
ADD CONSTRAINT csapp_center_bgs_bg_id_65c818f360c84dc5_fk_bg_bg_id
FOREIGN KEY (bg_id)
REFERENCES tiger.bg (bg_id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED;
Here is the precise error...
ERROR: insert or update on table "csapp_center_bgs" violates foreign key constraint "csapp_center_bgs_bg_id_65c818f360c84dc5_fk_bg_bg_id"
DETAIL: Key (bg_id)=(470370111002) is not present in table "bg".
********** Error **********
ERROR: insert or update on table "csapp_center_bgs" violates foreign key constraint "csapp_center_bgs_bg_id_65c818f360c84dc5_fk_bg_bg_id"
SQL state: 23503
Detail: Key (bg_id)=(470370111002) is not present in table "bg".
Why did this not work?! Any ideas? Here is \d+ bg...
Column | Type | Modifiers | Storage | Stats target | Description
----------+-----------------------+--------------------------------------------------+----------+--------------+-------------
gid | integer | not null default nextval('bg_gid_seq'::regclass) | plain | |
statefp | character varying(2) | | extended | |
countyfp | character varying(3) | | extended | |
tractce | character varying(6) | | extended | |
blkgrpce | character varying(1) | | extended | |
bg_id | character varying(12) | not null | extended | |
namelsad | character varying(13) | | extended | |
mtfcc | character varying(5) | | extended | |
funcstat | character varying(1) | | extended | |
aland | double precision | | plain | |
awater | double precision | | plain | |
intptlat | character varying(11) | | extended | |
intptlon | character varying(12) | | extended | |
the_geom | geometry | | main | |
Indexes:
"bg_pkey" PRIMARY KEY, btree (bg_id)
"idx_bg_geom" gist (the_geom) CLUSTER
Check constraints:
"enforce_dims_geom" CHECK (st_ndims(the_geom) = 2)
"enforce_geotype_geom" CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL)
"enforce_srid_geom" CHECK (st_srid(the_geom) = 4269)
Referenced by:
TABLE "csapp_center_bgs" CONSTRAINT "csapp_center_bgs_bg_id_65c818f360c84dc5_fk_bg_bg_id" FOREIGN KEY (bg_id) REFERENCES bg(bg_id) DEFERRABLE INITIALLY DEFERRED
Child tables: tiger_data.tn_bg
Has OIDs: no
And here is \d+ on csapp_...
Column | Type | Modifiers | Storage | Stats target | Description
-----------+-----------------------+---------------------------------------------------------------+----------+--------------+-------------
id | integer | not null default nextval('csapp_center_bgs_id_seq'::regclass) | plain | |
bg_id | character varying(12) | not null | extended | |
center_id | integer | not null | plain | |
Indexes:
"csapp_center_bgs_pkey" PRIMARY KEY, btree (id)
"csapp_center_bgs_5e94e25f" btree (bg_id)
"csapp_center_bgs_c63f1184" btree (center_id)
Foreign-key constraints:
"csapp_center_bgs_bg_id_65c818f360c84dc5_fk_bg_bg_id" FOREIGN KEY (bg_id) REFERENCES bg(bg_id) DEFERRABLE INITIALLY DEFERRED
"csapp_center_bgs_center_id_360e6806f7d3fee_fk_csapp_centers_id" FOREIGN KEY (center_id) REFERENCES csapp_centers(id) DEFERRABLE INITIALLY DEFERRED
Has OIDs: no
Here is the version:
version
------------------------------------------------------------------------------------------------------
PostgreSQL 9.3.5 on x86_64-unknown-linux-gnu, compiled by gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2, 64-bit
And here is my search path....
search_path
---------------
public, tiger
(1 row)
bg is in schema tiger and csapp_center_bgs is in schema public...
My first guess would be that you are dealing with two different tables named bg. One in the schema tiger, and another one in an undisclosed schema that comes before tiger in your search_path - or tiger is not in the search_path at all.
Find all tables named bg (case sensitive) in all schemas in the current db:
SELECT * FROM pg_tables WHERE tablename = 'bg';
To understand the search_path setting:
How does the search_path influence identifier resolution and the "current schema"
To understand the structure of a Postgres DB cluster:
What's the difference between a catalog and a schema in a relational database?
If that's not it, your index may be corrupted. I would first try a REINDEX:
REINDEX bg_pkey;
Inheritance!
I see in your added table definition:
Child tables: tiger_data.tn_bg
Suspecting that the row with bg_id ='470370111002' actually lives in the child table tiger_data.tn_bg. But your FK constraint references the parent table. FK constraints are not inherited.
What do you get if you query:
SELECT * FROM ONLY bg WHERE bg_id ='470370111002'
If my hypothesis holds, you get no row. Read the chapter Caveats on the Inheritance page of the manual.
Related:
Use triggers on inherited tables to replace foreign keys