how to set constraint and foreign key on a column - sql

i have the below posted tables. i would like to specify a constraint and foreign key on the column called fk_grid_cell in gridCellParticularPK table.
below is my attempts, but when i execute it, it gives a syntay error
the error i am receiving is:
syntax error at `constraint`
tables:
create table if not exists grid_cell(
fourCornersTreatmentAsGeoJSON text,
fourCornersBufferAsGeoJSON text,
primary key (fourCornersTreatmentAsGeoJSON,fourCornersBufferAsGeoJSON)
)
CREATE TABLE IF NOT EXISTS grid_cell_particular (
gridCellParticularPK serial primary key,
isTreatment boolean,
isBuffer boolean,
distanceFromTreatmentToNearestEdge float8,
distanceFromBufferToNearestEdge float8,
fk_grid_cell
constraint constrains_FK_gridCell_gridCellParticular
unique foreign key references grid_cell(fourCornersTreatmentAsGeoJSON,fourCornersBufferAsGeoJSON)
)

There are few things missing:
The columns you're using for the primary key on grid_cell do not exist in the table: fourCornersOfKeyWindowRepresentativeToTreatmentAsGeoJSON and fourCornersOfKeyWindowRepresentativeToBufferAsGeoJSON.
The column names on grid_cell suggest you're storing json strings, so you should be using the data type jsonb instead of text.
The foreign key columns declared on the constraint on grid_cell_particular also do not exist on the table itself. In order to create a foreign key you must map the foreign columns to existing columns on your table. You can name them as you want, e.g. fk_grid_cell_treatment and fk_grid_cell_buffer.
Unrelated:
Consider using INDENTITY columns instead of serial. Check this out: Don't use serial
CREATE TABLE IF NOT EXISTS grid_cell(
fourCornersTreatmentAsGeoJSON jsonb,
fourCornersBufferAsGeoJSON jsonb,
fourCornersOfKeyWindowRepresentativeToTreatmentAsGeoJSON jsonb,
fourCornersOfKeyWindowRepresentativeToBufferAsGeoJSON jsonb,
PRIMARY KEY (fourCornersOfKeyWindowRepresentativeToTreatmentAsGeoJSON,
fourCornersOfKeyWindowRepresentativeToBufferAsGeoJSON)
);
CREATE TABLE IF NOT EXISTS grid_cell_particular (
gridCellParticularPK serial PRIMARY KEY,
isTreatment boolean,
isBuffer boolean,
distanceFromTreatmentToNearestEdge float8,
distanceFromBufferToNearestEdge float8,
fk_grid_cell_treatment jsonb,
fk_grid_cell_buffer jsonb,
CONSTRAINT constrains_FK_gridCell_gridCellParticular
FOREIGN KEY (fk_grid_cell_treatment,fk_grid_cell_buffer)
REFERENCES grid_cell
(fourCornersOfKeyWindowRepresentativeToTreatmentAsGeoJSON,
fourCornersOfKeyWindowRepresentativeToBufferAsGeoJSON),
CONSTRAINT unique_fk
UNIQUE (fk_grid_cell_treatment,fk_grid_cell_buffer)
);

Related

How to reference a postgres table with multiple primary keys

How could I create a xref table with a reference to this table?
CREATE TABLE reviewer (
screen_name integer,
identity_provider text
CONSTRAINT identity PRIMARY KEY (screen_name, identity_provider)
);
This is what I've tried so far:
CREATE TABLE business_reviewer_xref (
reviewer_screen_name integer,
reviewer_identity_provider text,
CONSTRAINT reviewer_identity UNIQUE (reviewer_screen_name, reviewer_identity_provider),
reviewer_identity REFERENCES reviewer(identity)
);
CREATE TABLE business_reviewer_xref (
reviewer_screen_name integer,
reviewer_identity constraint REFERENCES reviewer(identity)
);
CREATE TABLE business_reviewer_xref (
reviewer_screen_name integer,
reviewer_identity REFERENCES reviewer(identity)
);
A table cannot have multiple primary keys. It can only have one or none. But a primary key can of course consist of more than one column (but at least of one of course). To reference such a multi column primary key, you need a corresponding column in the referencing table for each column in the primary key of the referenced column.
To define a foreign key constraint, list the corresponding columns in the referencing table in the same order as their counterparts occur in the primary key constraint in the referenced table in the defining tuple of the foreign key. Also keep the order in the definition of the referenced columns' tuple.
In your case:
CREATE TABLE business_reviewer_xref
(reviewer_screen_name integer,
reviewer_identity text,
FOREIGN KEY (reviewer_screen_name,
reviewer_identity)
REFERENCES reviewer
(screen_name,
identity));
Note that a foreign key constraint, in contrast to a primary key constraint, doesn't implicitly set a unique constraint. If you want uniqueness too, you'd have to define another constraint for that.

PostreSql: ERROR: column referenced in foreign key constraint does not exist

What might possibly gone wrong?
ERROR: column "parameter_id" referenced in foreign key constraint does not exist
1 statement failed.
So i created 2 tables(parameters and periods) with the commands;
create table parameters(
parameter_id serial primary key,
temperature real,
feels_good_temperature int,
humidity int,
max_uv_index int
);
and
create table periods(
period_id serial primary key,
time_stamp text
);
...and now i want to have a column, fk_paramter_id in periods table, as a foreign key to the parameters table
I tried achieving it with;
ALTER TABLE periods
ADD CONSTRAINT fk_parameter_id FOREIGN KEY (parameter_id)
REFERENCES parameters(parameter_id);
You first have to create and populate the column:
ALTER TABLE periods ADD parameter_id integer;
Then use UPDATEs to set the correct values.
Now you can define the constraint.
Note: the constraint (fk_paramter_id) is not a column; it is defined on a column (parameter_id).

ALTER TABLE query for foreign key constraint does not work

I'm a beginner and creating my own simple blockchain app for fun. The blockchain itself is fully functional. Now I'm trying to implement a database to store the data of the blockchain (right now I'm writing it to a .txt file). So I want to create the following database schema in sqlite:
CREATE TABLE `Blockchain`
(
`previous_hash` string NOT NULL ,
`timestamp` float NOT NULL ,
`signature_of_transactions` string NOT NULL ,
`index` bigint NOT NULL ,
PRIMARY KEY (`previous_hash`)
);
CREATE TABLE `Wallet`
(
`public_key` string NOT NULL ,
PRIMARY KEY (`public_key`)
);
CREATE TABLE `Transactions`
(
`signature` string NOT NULL ,
`sender` string NOT NULL ,
`recipient` string NOT NULL ,
`amount` float NOT NULL ,
PRIMARY KEY (`signature`)
);
CREATE TABLE `Peer_nodes`
(
`id` string NOT NULL ,
`public_key` string NOT NULL ,
PRIMARY KEY (`id`)
);
ALTER TABLE `Wallet`
ADD CONSTRAINT `fk_Wallet_public_key`
FOREIGN KEY(`public_key`) REFERENCES `Peer_nodes` (`public_key`);
ALTER TABLE `Transactions`
ADD CONSTRAINT `fk_Transactions_signature`
FOREIGN KEY(`signature`) REFERENCES `Blockchain` (`signature_of_transactions`);
ALTER TABLE `Transactions`
ADD CONSTRAINT `fk_Transactions_sender`
FOREIGN KEY(`sender`) REFERENCES `Wallet` (`public_key`);
ALTER TABLE `Transactions`
ADD CONSTRAINT `fk_Transactions_recipient`
FOREIGN KEY(`recipient`) REFERENCES `Wallet` (`public_key`);
Creating the tables with the columns etc. works fine with the script above. The ALTER TABLE queries do not work somehow. This is the following error message I receive:
ALTER TABLE Wallet ADD CONSTRAINT fk_Wallet_public_key FOREIGN KEY(public_key) REFERENCES Peer_nodes (public_key)
ERROR:
As you can see, it has no real error message. I haven't found a possible error in the queries themselves after searching a lot on the internet. What am I doing wrong? I try to do this via phpLitedmin, so maybe the problem is there?
SQLite's ALTER TABLE does not support adding constraints.
You have to include the constraints into the CREATE TABLE statements.
And as already noted by Gordon, foreign key constraints require the target to be a primary or candidate key.
Your foreign key reference is to the wrong column. It should be to the primary key, although it can be to a unique key.
As explained in the documentation:
Usually, the parent key of a foreign key constraint is the primary key
of the parent table. If they are not the primary key, then the parent
key columns must be collectively subject to a UNIQUE constraint or
have a UNIQUE index. If the parent key columns have a UNIQUE index,
then that index must use the collation sequences that are specified in
the CREATE TABLE statement for the parent table.
You should fix the table definition and add the foreign key to use the primary key.

PostgresQL Foreign Key Syntax Error

When attempting to create the second table in this respective database, I'm getting the following error message:
ERROR: syntax error at or near "REFERENCES"
LINE 3: master_directory REFERENCES auth_table (directory),
Here's the database structure that I attempted to create:
CREATE TABLE auth_table (
id SERIAL PRIMARY KEY,
directory VARCHAR,
image VARCHAR
)
CREATE TABLE master_table (
id SERIAL PRIMARY KEY,
master_directory references auth_table (directory),
master_image references auth_table (image)
)
Any reason why I'm receiving that error? Any help would be appreciated!
You've left the data type off, but that syntax error is the least of your problems.
Your foreign key references need to refer to unique column(s). So "auth_table" probably needs to be declared one of these ways. (And you probably want the second one, if your table has something to do with the paths to files.)
CREATE TABLE auth_table (
id SERIAL PRIMARY KEY,
directory VARCHAR not null unique,
image VARCHAR not null unique
);
CREATE TABLE auth_table (
id SERIAL PRIMARY KEY,
directory VARCHAR not null,
image VARCHAR not null,
unique (directory, image)
);
Those unique constraints mean quite different things, and each requires a different foreign key reference. Assuming that you want to declare "auth_table" the second way, "master_table" probably ought to be declared like one of these. (Deliberately ignoring cascading updates and deletes.)
CREATE TABLE master_table (
master_directory varchar not null,
master_image varchar not null,
primary key (master_directory, master_image),
foreign key (master_directory, master_image)
references auth_table (directory, image)
);
CREATE TABLE master_table (
id integer primary key,
foreign key (id) references auth_table (id)
);

SQLMetal - Foreign Key Constraint with multiple fields - Error

When I try to run SQLMetal on a sqlite database which defines a foreign key constraint on multiple fields, i get an error.
The table is as follows:
CREATE TABLE A (
a1 INTEGER,
a2 INTEGER,
PRIMARY KEY (a1,a2)
);
CREATE TABLE B (
b1 INTEGER,
b2 INTEGER,
b3 INTEGER,
b4 TEXT,
PRIMARY KEY (b1,b2,b3),
FOREIGN KEY (b1,b2) REFERENCES A (a1,a2)
);
The error message is:
"sqlmetal: Sequence contains more than one matching element"
Anybody knows how to resolve that problem?
I think the issue is that you can only have one primary key per table. Here's the blurb from the sqlite documentation:
"Each table in SQLite may have at most one PRIMARY KEY. If the keywords PRIMARY KEY are added to a column definition, then the primary key for the table consists of that single column. Or, if a PRIMARY KEY clause is specified as a table-constraint, then the primary key of the table consists of the list of columns specified as part of the PRIMARY KEY clause. If there is more than one PRIMARY KEY clause in a single CREATE TABLE statement, it is an error."