Tilbake

Flask 2.2

Utvidelse: Bruk MySQL Workbench som database

I Flask 2.1 lagret appen meldinger i SQLite-filen vegg.db. Her flytter vi datalaget til MySQL, slik at dere ser hvordan samme Flask-app kan bruke en database-server.

Hva bygger vi egentlig?

Dette er en liten, fullverdig web-applikasjon: nettleseren viser frontend, Flask er backend-serveren, og MySQL lagrer data. I Supabase-oppgaver håndteres mye av serverdelen av Supabase i skyen. Her gjør Flask den jobben selv, så dere ser hele flyten fra forespørsel til databasesvar.

Frontend

Nettleser

Brukeren fyller ut skjemaet og sender en HTTP-request til Flask.

HTTP
Backend

Flask-server

Python-koden tar imot data, validerer og sender SQL til databasen.

SQL
Database

MySQL

Data lagres i MySQL på port 3306 og kan sjekkes i Workbench.

Hva endrer seg?

Før

SQLite

Data lå i én lokal fil: vegg.db.

MySQL Server

Data lagres i en database som kan inspiseres i MySQL Workbench.

Uendret

Frontend

Dere kan bruke samme templates/index.html fra Flask 2.1.

Fase 1 - Opprett database i MySQL Workbench

  1. Åpne MySQL Workbench og koble til den lokale MySQL-serveren.
  2. Åpne et nytt SQL-vindu.
  3. Kjør SQL-en under.
create database if not exists flask_statusvegg
  character set utf8mb4
  collate utf8mb4_unicode_ci;

use flask_statusvegg;

create table if not exists meldinger (
  id int auto_increment primary key,
  alias varchar(30) not null default 'Anonym',
  tekst varchar(240) not null,
  tidspunkt timestamp not null default current_timestamp
);
Hvorfor utf8mb4? Da støtter databasen norske bokstaver og emoji bedre.

Fase 2 - Installer MySQL-driver i Flask-prosjektet

Bruk samme prosjektmappe som i Flask 2.1. Aktiver .venv først, og installer driveren mysql-connector-python.

source .venv/bin/activate
python3 -m pip install mysql-connector-python
Husk: Hver nye prosjektmappe med egen .venv starter med et tomt Python-miljø. Hvis dere lager en helt ny mappe for denne testen, må både flask og mysql-connector-python installeres der.
Dette må gjøres mens maskinen har internettilgang. Etter installasjon kan appen kjøres lokalt.

Fase 3 - Sett MySQL-passord som miljøvariabel

Ikke skriv databasepassordet direkte inn i app.py. Legg det heller inn som en miljøvariabel i terminalen før du starter Flask.

Viktig: Dette er passordet til MySQL-brukeren deres, ofte root-passordet fra installasjonen. Workbench kan ha lagret passordet, men Flask kjenner det ikke automatisk. Hvis dere får using password: NO, er passordet ikke sendt inn til Python-programmet.
export MYSQL_PASSWORD="DITT_MYSQL_PASSORD"

Kommandoen gjelder for terminalvinduet du står i. Hvis du åpner et nytt terminalvindu, må den kjøres på nytt.

Fase 4 - Bytt ut app.py

Denne versjonen bruker MySQL i stedet for SQLite. templates/index.html kan være den samme som i Flask 2.1.

import os
import mysql.connector
from flask import Flask, render_template, request, redirect

app = Flask(__name__)

MYSQL_CONFIG = {
    "host": "127.0.0.1",
    "port": 3306,
    "user": "root",
    "password": os.environ.get("MYSQL_PASSWORD"),
    "database": "flask_statusvegg",
}


def get_db():
    if not MYSQL_CONFIG["password"]:
        raise RuntimeError("Sett MYSQL_PASSWORD i terminalen før du starter appen.")

    return mysql.connector.connect(**MYSQL_CONFIG)


def init_db():
    conn = get_db()
    cursor = conn.cursor()

    try:
        cursor.execute("""
            create table if not exists meldinger (
                id int auto_increment primary key,
                alias varchar(30) not null default 'Anonym',
                tekst varchar(240) not null,
                tidspunkt timestamp not null default current_timestamp
            )
        """)
        conn.commit()
    finally:
        cursor.close()
        conn.close()


init_db()


@app.route("/")
def index():
    conn = get_db()
    cursor = conn.cursor()

    try:
        cursor.execute("""
            select alias, tekst, date_format(tidspunkt, '%H:%i:%s')
            from meldinger
            order by id desc
        """)
        alle_meldinger = cursor.fetchall()
    finally:
        cursor.close()
        conn.close()

    return render_template("index.html", meldinger=alle_meldinger)


@app.route("/send", methods=["POST"])
def send_melding():
    bruker_alias = (request.form.get("alias") or "").strip() or "Anonym"
    melding_tekst = (request.form.get("tekst") or "").strip()

    if len(bruker_alias) > 30:
        return "Alias kan maks være 30 tegn.", 400

    if not melding_tekst:
        return "Meldingen kan ikke være tom.", 400

    if len(melding_tekst) > 240:
        return "Meldingen kan maks være 240 tegn.", 400

    conn = get_db()
    cursor = conn.cursor()

    try:
        cursor.execute(
            "insert into meldinger (alias, tekst) values (%s, %s)",
            (bruker_alias, melding_tekst)
        )
        conn.commit()
    finally:
        cursor.close()
        conn.close()

    return redirect("/")


if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000)
Lab-notat: Flask-serveren er fortsatt åpen på LAN. Bruk alias/gruppenavn, ikke private opplysninger.

Fase 5 - Kjør og sjekk i Workbench

  1. Start Flask med python3 app.py.
  2. Åpne appen i nettleseren og send noen meldinger.
  3. Gå tilbake til MySQL Workbench og kjør SQL-spørringen under.
use flask_statusvegg;

select id, alias, tekst, tidspunkt
from meldinger
order by id desc;

Her ser dere at Flask ikke lagrer data i en fil lenger. Dataene ligger i MySQL-tabellen meldinger.

Vanlige feil

Feil Hva betyr det? Løsning
No module named mysql MySQL-driveren er ikke installert i riktig .venv. Kjør source .venv/bin/activate og installer mysql-connector-python.
Access denied Feil brukernavn/passord til MySQL. Sjekk MySQL-passordet og kjør export MYSQL_PASSWORD="..." på nytt.
Unknown database Databasen er ikke opprettet i Workbench. Kjør SQL-en i Fase 1.