66 Andmebaasid (back-end)

Andmebaaside jaoks on meil vaja paigaldada moodul Flask-SQLAlchemy. Selleks valime Thonny menüüst Tööriistad → Halda lisapakke (Tools → Mangage Packages), seejärel kirjutame otsinguaknasse flask-sqlalchemy ja vajutame Otsi pakki PyPI-st (Find package from PyPI). Nüüd saab installida Flask-SQLAlchemy mooduli, vajutades nuppu Installi (Install).

Flask-SQLAlchemy paigaldamine

Seejärel loome faili blogi.py ja impordime selle mooduli, lisades faili rea from flask_sqlalchemy import SQLAlchemy.

Seega algus on meil nüüd järgnev:

from flask import Flask, render_template
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)

Teeme läbi pikema näite, mille tulemus on rakendus, kus kasutajal on võimalik lisada blogipostitusi, sisestades veebivormi kaudu autori nime, postituse pealkirja ja postituse sisu. Postitused kuvatakse veebilehel ja salvestatakse andmebaasi.

Kõigepealt kirjutame faili blogi.py kõik vajaliku, et luua meie näite jaoks sobiv andmebaas. Järgneva reaga määrame, kuhu andmebaas salvestatakse. Siis määrame muudatuste jälgimise süsteemi seaded ning seejärel lisame rea andmebaasi postitused.db loomiseks. Reaalselt aga andmebaasi veel ei looda.

app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///postitused.db' # Määrame, kuhu andmebaas salvestatakse
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False # määrame muudatuste jälgimise süsteemi seaded
db = SQLAlchemy(app) # loome andmebaasi

Seejärel määrame, millised veerud andmebaasis on ja millist tüüpi andmed on. Peamised andmetüübid on Integer, String(pikkus), Text, DateTime, Float ja Boolean.

class Postitus(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    pealkiri = db.Column(db.String(100), nullable=False)
    sisu = db.Column(db.Text, nullable=False)
    autor = db.Column(db.String(20), nullable=False, default='Toimetaja')
    aeg = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)

Siin on id unikaalne tunnus, seega määrame selle primaarseks võtmeks (primary_key=True). Meil on vaja, et nii pealkiri, sisu, autor kui ka aeg oleks alati täidetud – seega lisasime nullable=False. Praeguses näites kirjutatakse autori nime asemel Toimetaja, kui nime ei sisestata. Ajaks määratakse postituse sisestamise aeg.

Kasutasime datetime moodulit, mida on vaja importida. Seega lisame from datetime import datetime

Seega algus on meil nüüd järgnev:

from flask import Flask, render_template
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
app = Flask(__name__)

Nüüd kirjutame osa, mis väljastab info postituse kohta. Selle osa lisame klassi nimega Postitus.

def __repr__(self):
    return 'Postitus ' + str(self.id)

Kokku on klassi sisu järgnev:

class Postitus(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    pealkiri = db.Column(db.String(100), nullable=False)
    sisu = db.Column(db.Text, nullable=False)
    autor = db.Column(db.String(20), nullable=False, default='Toimetaja')
    aeg = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
    def __repr__(self):
        return 'Postitus ' + str(self.id)

Meil on nüüd failis olemas info andmebaasi kohta, kuid andmebaas ise ei ole veel loodud. Kirjutame käsureale from blogi import db, siis vajutame Enter ja db.create_all(). Nüüd reaalselt luuakse andmebaas vastavalt nendele reeglitele, mis enne kirjutasime.

>>> from blogi import db
>>> db.create_all()

Kui kõik õnnestus, tekkis blogi.py-ga samasse kausta fail postitused.db.

Päringud, andmete lisamine, muutmine ja kustutamine

Enne päringute tegemist on käsurealt vaja importida andmebaas ja klass.

>>> from blogi import db
>>> from blogi import Postitus

Kui tahame väljastada kõik postitused, siis valime käsureal Postitus.query.all(). Kuna me ei ole andmebaasi veel ühtegi postitust lisanud, kuvatakse tühi järjend.

>>> Postitus.query.all()
[]

Vaatame kõigepealt, kuidas andmeid käsurealt andmebaasi lisada. Loome andmebaasi lisamiseks esimese postituse ja kirjutame selle käsureale ning seejärel vajutame Enter.

db.session.add(Postitus(pealkiri='Ilus päev', sisu='Täna on ilus päev.', autor='Heidi'))

Sarnaselt loome ka teise ja kolmanda postituse.

db.session.add(Postitus(pealkiri='Päikseline hommik', sisu='Täna on päikseline hommik.', autor='Elle'))
db.session.add(Postitus(pealkiri='Sombune õhtu', sisu='Täna on sombune õhtu.', autor='Elle'))

Nüüd lisame need andmebaasi.

db.session.commit()

Kui nüüd kirjutame Postitus.query.all(), saame tulemuseks [Postitus 1, Postitus 2, Postitus 3]. Seega need kolm postitust on andmebaasis olemas. Tulemuse kuju sõltub sellest, et määrasime klassis Postitus, et tagastatakse 'Postitus ' + str(self.id).

>>> Postitus.query.all()
[Postitus 1, Postitus 2, Postitus 3]

Kui kirjutame käsureale Postitus.query.all()[0],kuvatakse esimese postituse info id alusel. Sama tulemuse annavad ka Postitus.query.first() ja Postitus.query.get(1).

>>> Postitus.query.all()[0]
Postitus 1

Kui kirjutame käsureale Postitus.query.all()[0].pealkiri, kuvatakse esimese postituse pealkiri, kasutades postituse otsimiseks selle indeksit. Muutujale pealkiri andsime väärtuse klassis Postitus.

>>> Postitus.query.all()[0].pealkiri
'Ilus päev'

Analoogselt saame vaadata ka teiste postituste andmeid. Näiteks Postitus.query.all()[1].sisu kuvab teise postituse sisu.

>>> Postitus.query.all()[1].sisu
'Täna on päikseline hommik.'

Kui aga sisestame indeksi, millele vastavat postitust andmebaasis ei ole, tuleb veateade. Sama veateade tuleb sisestades Postitus.query.all()[5] või Postitus.query.all()[5].sisu.

>>> Postitus.query.all()[5].sisu
Traceback (most recent call last):
  File "<pyshell>", line 1, in <module>
IndexError: list index out of range

Postitus.query.get(5) aga ei anna tulemuseks midagi. Kui kirjutame print(Postitus.query.get(5)), väljastatakse None.

Andmeid saame ka filtreerida. Näiteks filtreerime kõik postitused, mille autor on Elle.

>>> Postitus.query.filter_by(autor='Elle').all()
[Postitus 2, Postitus 3]

Nüüd leiame 2. postituse (indeksiga 1), mille autor on Elle.

>>> Postitus.query.filter_by(autor='Elle')[1]
Postitus 3

Kui tahame andmebaasis andmeid muuta, siis saame seda teha nii, et omistame uue väärtuse. Meie näites oli 2. postituse autor Elle. Kui tahame selle autori nime muuta, saame teha seda järgnevalt:

>>> Postitus.query.get(2).autor = 'Heidi'
>>> db.session.commit()

Kui tahame kontrollida, kas nüüd on 2. postituse autor Heidi, saame seda teha nii:

>>> Postitus.query.get(2).autor
'Heidi'

Kui tahame kustutada näiteks 3. postituse andmebaasist, saame teha seda nii:

>>> db.session.delete(Postitus.query.get(3))
>>> db.session.commit()

Kui tahame kontrollida, kas meil on nüüd 3 postituse asemel 2, saame seda teha nii:

>>> Postitus.query.all()
[Postitus 1, Postitus 2]

 

Litsents

Icon for the Creative Commons Attribution 4.0 International License

Tarkvaraarendus. 2. trükk on loodud Eno Tõnisson, Tauno Palts, Kaarel Tõnisson, Heidi Meier, Merilin Säde, Ago Luberg, Birgy Lorenz, Einar Kivisalu, Meelis Antoi, ja Säde Mai Krusberg poolt Creative Commons Attribution 4.0 International License litsentsi alusel, kui pole teisiti märgitud.

Jaga seda raamatut