Context
We're building a blog for an intro. to databases course project.
In our blog, we want to be able to set Labels
on Posts
. The Labels
can't exist by themselves, they only do so if they are related to a Posts
. This way, Labels
that are not used by any Posts
shouldn't stay in the database.
More than one Label
can belong to a single Post
, and more than a single Post
can use a Label
.
We are using both SQLite3 (locally/testing) and PostgreSQL (deployment).
Implementation
Here is the SQL (SQLite3 flavor) that we use to create those two tables, along with the relationship table:
Posts
CREATE TABLE IF NOT EXISTS Posts(
id INTEGER PRIMARY KEY AUTOINCREMENT,
authorId INTEGER,
title VARCHAR(255),
content TEXT,
imageURL VARCHAR(255),
date DATETIME,
FOREIGN KEY (authorId) REFERENCES Authors(id) ON DELETE SET NULL
)
Labels
CREATE TABLE IF NOT EXISTS Labels(
id INTEGER PRIMARY KEY AUTOINCREMENT,
name VARCHAR(255) UNIQUE,
-- This is not working:
FOREIGN KEY (id) REFERENCES LabelPosts(labelId) ON DELETE CASCADE
)
LabelPosts (relation between Post
[1..*] -- * Label
)
CREATE TABLE IF NOT EXISTS LabelPosts(
postId INTEGER,
labelId INTEGER,
PRIMARY KEY (postId, labelId),
FOREIGN KEY (postId) REFERENCES Posts(id) ON DELETE CASCADE
)
Problem
Using SQLite3,
Labels
are not deleted from the database when I remove all references to it from theLabelPosts
table. I think for the reason given by Postgres, despite SQLite accepting the table without warning.PostgreSQL complains that
labelId
is not unique withinLabelPosts
, which is true and also required, since it's many-to-many:
pq: S:"ERROR" R:"transformFkeyCheckAttrs" L:"6511" C:"42830" F:"tablecmds.c"
M:"there is no unique constraint matching given keys for referenced table \"labelposts\""
So I understand that I'm doing my constraint wrong. However I don't know how to do it properly.