switched from sqlite3 to flask_sqlalchemy

This commit is contained in:
eclipse 2025-04-20 22:53:08 +02:00
parent 9ebbbeab09
commit 1dc0ea98e2
6 changed files with 78 additions and 61 deletions

View File

@ -1,2 +1,5 @@
flask
python-dotenv
python-dotenv
click
flask-debugtoolbar
flask-sqlalchemy

View File

@ -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

View File

@ -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()
def init_db(app):
db.init_app(app)
with app.app_context():
db.reflect()

27
the_works/models.py Normal file
View File

@ -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")

View File

@ -24,13 +24,13 @@
<tbody>
{% for row in rows %}
<tr>
<td>{{row["Titel"]}}</td>
<td>{{row["Untertitel"]}}</td>
<td>{{row["Reihe"]}}</td>
<td>{{row["Textform"]}}</td>
<td>{{row["Originalsprache"]}}</td>
<td><a href="{{ url_for('views.text_update', id=row['ID']) }}">edit</a></td>
<td><a href="{{ url_for('views.text_delete', id=row['ID']) }}">delete</a></td>
<td>{{ row.Texte.Titel }}</td>
<td>{{ row.Texte.Untertitel }}</td>
<td>{{ row.Reihen.Reihentitel }}</td>
<td>{{ row.Textformen.Textform }}</td>
<td>{{ row.Sprachen.Sprache }}</td>
<td><a href="{{ url_for('views.text_update', id=row.Texte.ID) }}">edit</a></td>
<td><a href="{{ url_for('views.text_delete', id=row.Texte.ID) }}">delete</a></td>
</tr>
{% endfor %}
</tbody>
@ -56,7 +56,7 @@
Reihe
<select name="text_reihe" aria-label="Der Text gehört zur Reihe …">
<option selected value="">keine Reihe</option>
{% for r in reihen %}<option value="{{ r['ID'] }}">{{ r['Reihentitel']}}</option>
{% for r in reihen %}<option value="{{ r.ID }}">{{ r.Reihentitel }}</option>
{% endfor %}
</select>
</label>
@ -64,7 +64,7 @@
Textform (erforderlich)
<select name="text_textform" aria-label="Textform" required>
<option selected disabled value="">Textform auswählen …</option>
{% for tf in textformen %}<option value="{{ tf['ID'] }}">{{ tf['Textform']}}</option>
{% for tf in textformen %}<option value="{{ tf.ID }}">{{ tf.Textform }}</option>
{% endfor %}
</select>
</label>
@ -72,7 +72,7 @@
Sprache (erforderlich)
<select name="text_sprache" aria-label="Sprache des Textes" required>
<option selected disabled value="">Sprache auswählen …</option>
{% for s in sprachen %}<option value="{{ s['ID'] }}">{{ s['Sprache']}}</option>
{% for s in sprachen %}<option value="{{ s.ID }}">{{ s.Sprache }}</option>
{% endfor %}
</select>
</label>

View File

@ -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():