I am choosing my stack based upon what works well with Flask. Since Flask depends on Jinja2, Werkzeug, and Click; these are libraries that I am using for my Flask app. The only outside libraries I am using are Flask-SQLAlchemy and Markdown. Flask-SQLAlchemy is an Object Relational Mapper that makes it easy to integrate your code and database together. A major advantage of SQLAlchemy is that it can be used with SQLite3, MySQL, or PostgreSQL. So for development, to make my life easier, I am using SQLite3; but in production I’ll probably switch over to PostgreSQL. My use of the Markdown library is probably fairly obvious, but I haven’t even started on that part of the app. Ultimately, I want the blog CMS to store the individual entries externally rather than in the database. The database itself will actually house metadata about each entry instead. I think that this will give me more flexibility and also more data protection. For example, here is myModels.py
file:
from datetime import datetime
from flask_sqlalchemy import SQLAlchemy
# Create an instance of the SQLAlchemy class called db
db = SQLAlchemy()
# Each Class represents a table within the database
# The Author table contains login information and meta information about each other
class Author(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(100), unique=True, nullable=False)
passwd_hash = db.Column(db.String(100), unique=True, nullable=False)
first_name = db.Column(db.String(50), unique=False, nullable=False)
last_name = db.Column(db.String(50), unique=False, nullable=False)
admin = db.Column(db.Boolean(), default=False)
entries = db.relationship('Entry', foreign_keys='entry.id', backref='entries', lazy=True)
def __repr__(self):
return '<Author %r>' % self.username
# The Entry table only contains metadata about each post.
# f"{DATA_DIRECTORY}
class Entry(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(35), nullable=False)
genre = db.Column(db.String(25), nullable=False)
content_path = db.Column(db.String(150), nullable=False)
date_created = db.Column(db.DateTime(timezone=True), default=datetime.utcnow())
author_id = db.Column(db.Integer, db.ForeignKey('author.id'))
def __repr__(self):
return '<Entry %r>' % self.title
# Note: Entries will be stored and accessed at
# f"{DATA_DIRECTORY}/{self.genre}/{self.title}'
"""
I learned about Normalization in class,
so I am honestly worried about whether
or not my data is normalized. If it isn't please
tell me. Thanks
"""
The idea is to have entries organized neatly in a single data directory for easy backups. Inside the data directory, there will be more directories that categorize each item by genres, and finally in each genre will be yet more directories - one for each entry. Inside an entry directory there will be HTML files or something and images relevant to the entry if any. Each HTML file represents a page of the post like the pages of an ebook. My blog isn’t really a conventional blog, and I really don’t like calling it a blog. It’s really an outlet for me to post stories. I am a huge bookworm, and a pretty good writer according to my Freshman comp professor. Even in high school I liked to do a lot of creative writing projects. Now that I am out I don’t get that opportunity anymore, so I am making an opportunity for myself.
I know this last part is more than what you asked, but I felt it important to specify that my database is only going to contain metadata. It will not contain the data itself.
P.S, I am also using Python’s TOML library since my application’s config file is loaded from a TOML file.