I'm trying to learn Peewee and Bottle by making a book note-taking application.
Say I have the following entities:
Subject
Book
Chapter
Note
Tag
I would like to be able to make Notes for Chapters, Books, and Subjects.
In a DB, you would do:
create table noteable (
noteable_id INT AUTO_INCREMENT PRIMARY KEY
,type VARCHAR(10) NOT NULL CHECK (type in ('SUBJECT','BOOK','CHAPTER','NOTE'))
);
create table subject (
subject_id INT AUTO_INCREMENT PRIMARY KEY
,noteable_id INT UNIQUE REFERENCES noteable (noteable_id)
,...
);
create table book (
book_id INT AUTO_INCREMENT PRIMARY KEY
,subject_id INT NOT NULL REFERENCES subject (subject_id)
,noteable_id INT UNIQUE REFERENCES noteable (noteable_id)
,...
);
create table chapter(
chapter_id INT AUTO_INCREMENT PRIMARY KEY
,book_id INT NOT NULL REFERENCES book (book_id)
,noteable_id INT UNIQUE REFERENCES noteable(noteable_id)
,...
);
create table note(
note_id INT AUTO_INCREMENT PRIMARY KEY
,noteable_id INT UNIQUE REFERENCES noteable(noteable_id)
,...
);
(If you wanted a M:N relationship between note and notable, you would do a note_notable bridge table as well).
You would have before insert triggers on subject, book, and chapter that would insert a row into noteable, retrieve the new row's noteable_id, and use that on the incoming row.
I'm assuming that if you are using an ORM like Peewee you would want to do that in application logic rather than triggers.
How can I implement this model in Peewee?
Here is how I did it. I couldn't find a native way in Peewee to implement inheritance so I just rolled it myslef. If there is a better way, please provide your answer and I'll award it.
(if you wished to have a many to many relationship between notes and notable, you would have to define a NoteNotable class with foreign keys and remove the FK from Note)
You can define a helper method to left join whichever class with notes:
You can iterate over it like:
Here are the results from a
SELECT * FROM NOTABLE;Here are the results from a
SELECT * FROM NOTE;