diff --git a/DEPENDENCIES.md b/DEPENDENCIES.md index 5a4a2b9..31549d6 100644 --- a/DEPENDENCIES.md +++ b/DEPENDENCIES.md @@ -1,2 +1,5 @@ flask -python-dotenv \ No newline at end of file +python-dotenv +click +flask-debugtoolbar +flask-sqlalchemy diff --git a/the_works/__init__.py b/the_works/__init__.py index 4bd540c..5ab5cba 100644 --- a/the_works/__init__.py +++ b/the_works/__init__.py @@ -1,19 +1,35 @@ import os from dotenv import load_dotenv from flask import Flask -from the_works import views, database +from the_works.database import init_db +from flask_debugtoolbar import DebugToolbarExtension -load_dotenv() def create_app(): app = Flask(__name__) + # read config values + load_dotenv() app.config.from_prefixed_env() - print(f"Current Environment: {os.getenv('ENVIRONMENT')}") - print(f"Using Database: {app.config.get('DATABASE')}") + if os.getenv("SQLALCHEMY_DATABASE_DIALECT") == "sqlite": + app.config['SQLALCHEMY_DATABASE_URI'] = "sqlite:///" + os.path.abspath(app.root_path + "/..") + "/" + os.getenv("SQLALCHEMY_DATABASE_SQLITE_FILENAME") + else: + pass + + # DEBUG + app.config["SQLALCHEMY_ECHO"] = True + + print(f"Current Environment: " + app.config['ENVIRONMENT']) + print(f"SQLAlchemy DB URI: " + app.config['SQLALCHEMY_DATABASE_URI']) - database.init_app(app) + # initialize database + init_db(app) + # register blueprints + from the_works import views app.register_blueprint(views.bp) + # load debug toolbar + toolbar = DebugToolbarExtension(app) + return app diff --git a/the_works/database.py b/the_works/database.py index b9086a9..c5bd12c 100644 --- a/the_works/database.py +++ b/the_works/database.py @@ -1,28 +1,8 @@ -import sqlite3 -import click -from flask import current_app, g +from flask_sqlalchemy import SQLAlchemy -def init_app(app): - app.teardown_appcontext(close_db) - app.cli.add_command(init_db_command) +db = SQLAlchemy() -@click.command("init-db") -def init_db_command(): - db = get_db() - with current_app.open_resource("schema.sql") as f: - db.executescript(f.read().decode("utf-8")) - click.echo("You successfully initialized the database!") - -def get_db(): - if "db" not in g: - g.db = sqlite3.connect( - current_app.config["DATABASE"], - detect_types=sqlite3.PARSE_DECLTYPES, - ) - g.db.row_factory = sqlite3.Row - return g.db - -def close_db(e=None): - db = g.pop("db", None) - if db is not None: - db.close() \ No newline at end of file +def init_db(app): + db.init_app(app) + with app.app_context(): + db.reflect() \ No newline at end of file diff --git a/the_works/models.py b/the_works/models.py new file mode 100644 index 0000000..0de7d2e --- /dev/null +++ b/the_works/models.py @@ -0,0 +1,27 @@ +from the_works.database import db +from sqlalchemy.orm import relationship + +class Texte(db.Model): + __table__ = db.Model.metadata.tables['Texte'] + reihe = relationship("Reihen", back_populates="texte") + textform = relationship("Textformen", back_populates="texte") + sprache = relationship("Sprachen", back_populates="texte") + + def __repr__(self): + return f"Texte(ID={self.ID}, Titel={self.Titel}, Untertitel={self.Untertitel}, Reihe={self.Reihe})" + +class Werke(db.Model): + __table__ = db.Model.metadata.tables['Werke'] + +class Reihen(db.Model): + __table__ = db.Model.metadata.tables['Reihen'] + texte = relationship("Texte", back_populates="reihe") + +class Textformen(db.Model): + __table__ = db.Model.metadata.tables['Textformen'] + texte = relationship("Texte", back_populates="textform") + +class Sprachen(db.Model): + __table__ = db.Model.metadata.tables['Sprachen'] + texte = relationship("Texte", back_populates="sprache") + diff --git a/the_works/templates/views/texte.html b/the_works/templates/views/texte.html index c280383..ceadc19 100644 --- a/the_works/templates/views/texte.html +++ b/the_works/templates/views/texte.html @@ -24,13 +24,13 @@ {% for row in rows %} - {{row["Titel"]}} - {{row["Untertitel"]}} - {{row["Reihe"]}} - {{row["Textform"]}} - {{row["Originalsprache"]}} - edit - delete + {{ row.Texte.Titel }} + {{ row.Texte.Untertitel }} + {{ row.Reihen.Reihentitel }} + {{ row.Textformen.Textform }} + {{ row.Sprachen.Sprache }} + edit + delete {% endfor %} @@ -56,7 +56,7 @@ Reihe @@ -64,7 +64,7 @@ Textform (erforderlich) @@ -72,7 +72,7 @@ Sprache (erforderlich) diff --git a/the_works/views.py b/the_works/views.py index fcc5ec8..9d4df91 100644 --- a/the_works/views.py +++ b/the_works/views.py @@ -1,5 +1,7 @@ from flask import Blueprint, render_template, request, redirect, flash, url_for -from the_works.database import get_db +from the_works.database import db +from the_works.models import Texte, Reihen, Sprachen, Textformen +from sqlalchemy import select bp = Blueprint("views", __name__) @@ -9,24 +11,13 @@ def home(): @bp.route("/texte") def texte_show(): - db = get_db() - rows = db.execute( - """SELECT - t.ID as ID, - t.Titel AS Titel, - t.Untertitel AS Untertitel, - r.Reihentitel AS Reihe, - f.Textform AS Textform, - s.Sprache AS Originalsprache - FROM Texte t - LEFT JOIN Reihen r ON t.Reihe = r.ID - LEFT JOIN Textformen f ON t.Textform = f.ID - LEFT JOIN Sprachen s ON t.Originalsprache = s.ID;""" - ).fetchall() - reihen = db.execute("SELECT ID, Reihentitel from Reihen").fetchall() - textformen = db.execute("SELECT ID, Textform from Textformen").fetchall() - sprachen = db.execute("SELECT ID, Sprache from Sprachen").fetchall() - return render_template("views/texte.html", rows=rows, reihen=reihen, textformen=textformen, sprachen=sprachen) + stmt = ( + select(Texte, Reihen, Textformen, Sprachen) + .join(Texte.textform, isouter=True) + .join(Texte.reihe, isouter=True) + .join(Texte.sprache, isouter=True) + ) + return render_template("views/texte.html", rows=db.session.execute(stmt), reihen=db.session.scalars(select(Reihen)), textformen=db.session.scalars(select(Textformen)), sprachen=db.session.scalars(select(Sprachen))) @bp.route("/texte/create", methods=["POST"]) def text_create():