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,
Labelsare not deleted from the database when I remove all references to it from theLabelPoststable. I think for the reason given by Postgres, despite SQLite accepting the table without warning.PostgreSQL complains that
labelIdis 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.