#!/wwwhome/home/tjlahton/public_html/cgi-bin/tiea2080/venv/bin/python # -*- coding: utf-8 -*- from flask import Flask, session, redirect, url_for, escape, request, Response, render_template import sys import sqlite3 import os import werkzeug.exceptions app = Flask(__name__) app.debug = True # set the secret key. keep this really secret: app.secret_key = b'\xf5\x18\x8cV\xce\xdd\xfc\x90\xd5\xee\x1b\xbf\xe0\xda\xc5\x87\xc8\xac\xa0\xe9#4"R' @app.route('/reseptit') def reseptit(): # oletetaan että sovellus on kansiossa /~omatunnus/cgi-bin/ties4080/ohjaus3/ # ja tietokanta on kansiossa /~omatunnus/hidden/ # os.path.abspath muuntaa suhteellisen polun absoluuttiseksi, joka taasen kelpaa sqlitelle try: # asetetaan samalla autocommit-moodi päälle (isolation_level=none) con = sqlite3.connect(os.path.abspath('../../../hidden/resepti'), isolation_level=None) con.execute("PRAGMA foreign_keys = ON") # voidaan käsitellä palautettuja tietueita niiden kenttien nimillä con.row_factory = sqlite3.Row sql = """ SELECT * FROM resepti """ cur = con.cursor() cur.execute(sql) # valmistellaan kysely ja sijoitetaan dynaamisen arvon tilalle :lkm-muuttuja sql = '''SELECT Nimi, Kuvaus, Henkilomaara, ReseptiID, RuokaLajiID FROM Resepti WHERE henkilomaara = :lukumaara ''' lkm = 4 cur.execute( sql, {"lukumaara":lkm}) # Lisääminen. Tämä epäonnistuu, koska on jo lisätty samalla id:llä sql = '''INSERT INTO resepti (Nimi, Kuvaus, Henkilomaara, RuokalajiID, ReseptiID) VALUES (:nimi, :kuvaus, :henkilomaara, :ruokalaji, :reseptiid) ''' lkm = 4 nimi = 'Makaronilaatikko' kuvaus = 'Herkkuruoka' henkilomaara = 3 # cur.execute( sql, {"nimi":nimi, "kuvaus":kuvaus, "henkilomaara": henkilomaara, "ruokalaji": 2, "reseptiid": 10}) # con.commit() # Lisääminen. Tämä onnistuu, koska ei itse anneta reseptiid:tä ollenkaan vaan annetaan tietokannan # hoitaa se. Toimii vain koska tietokannassa kyseinenn kenttä on tyyppiä autoincrement: # ReseptiID INTEGER PRIMARY KEY AUTOINCREMENT, sql = '''INSERT INTO resepti (Nimi, Kuvaus, Henkilomaara, RuokalajiID) VALUES (:nimi, :kuvaus, :henkilomaara, :ruokalaji) ''' lkm = 4 nimi = 'Makaronilaatikko' kuvaus = 'Herkkuruoka' henkilomaara = 3 cur.execute( sql, {"nimi":nimi, "kuvaus":kuvaus, "henkilomaara": henkilomaara, "ruokalaji": 2}) # Poista. resepti sql = '''DELETE FROM resepti WHERE reseptiID = :id ''' cur.execute( sql, {"id":2}) # Poista. ruokalaji. Tämä kaatuu, koska ruokalaji on käytössä ja viite-eheys estää poistamisen sql = '''DELETE FROM ruokalaji WHERE ruokalajiID = :id ''' # cur.execute( sql, {"id":2}) # Poista useita reseptejä. sql = '''DELETE FROM resepti WHERE reseptiid > 10 ''' cur.execute(sql) # Tee päivitys sql = '''UPDATE resepti SET henkilomaara = :maara WHERE reseptiID = :reseptiID ''' cur.execute(sql, {"maara":7, "reseptiID": 3}) sql = """ SELECT nimi as Nimi, kuvaus as Kuvaus, henkilomaara as Henkilomaara FROM resepti """ cur.execute(sql) # suoritetaan kysely reseptit = cur.fetchall() #haetaan kaikki kyselyn tulokset sql = """ SELECT nimi as Nimi, kuvaus as Kuvaus FROM Ruokalaji """ cur.execute(sql) # suoritetaan kysely ruokalajit = cur.fetchall() #haetaan kaikki kyselyn tulokset sql = """ SELECT ruokalaji.nimi AS ruokalaji, resepti.nimi AS resepti FROM resepti, ruokalaji WHERE ruokalaji.ruokalajiID = resepti.ruokalajiID ORDER BY ruokalaji.nimi, resepti.nimi """ cur.execute(sql) # suoritetaan kysely ruokareseptit = cur.fetchall() #haetaan kaikki kyselyn tulokset sql = """ SELECT ruokalaji.nimi AS ruokalaji, resepti.nimi AS resepti FROM ruokalaji LEFT OUTER JOIN resepti ON ruokalaji.ruokalajiID = resepti.ruokalajiID ORDER BY ruokalaji.nimi, resepti.nimi """ cur.execute(sql) # suoritetaan kysely ruokareseptit_all = cur.fetchall() #haetaan kaikki kyselyn tulokset # seuraavaa ei tarvita nyt kun autocommit on päällä eli kaikki on jo commitoitu # con.commit() # kommitoidaan kaikki edellä tehdyt muutokset. Jos tätä ei tehdä niin mikään edellä tehdyistä ei jää voimaan # Lisääminen transaktion avulla. # koska autocommit on päällä, täytyy transaktio aloittaa BEGIN-komennolla cur.execute( "BEGIN" ) sql = '''INSERT INTO ruokalaji (Nimi, Kuvaus, ruokalajiID) VALUES (:nimi, :kuvaus, :ruokalajiid ) ''' nimi = 'Salaiset ruuat' kuvaus = 'Ihan oma herkut' virheet = 0 try: cur.execute( sql, {"nimi":nimi, "kuvaus":kuvaus, "ruokalajiid": 33}) except sqlite3.Error: virheet += 1 sql = '''INSERT INTO resepti (Nimi, Kuvaus, henkilomaara, ruokalajiid, reseptiID) VALUES (:nimi, :kuvaus, :henkilomaara, :ruokalaji, :reseptiid ) ''' nimi = 'Salainen ruoka' kuvaus = 'namnam' try: # tämä epäonnistuu, koska reseptiid 1 on jo käytössä # tulee siis virhe ja transaktio perutaan eikä myöskään edellä lisätty ruokalaji 'Salaiset ruuat' # tallennu tietokantaan cur.execute( sql, {"nimi":nimi, "kuvaus":kuvaus, "henkilomaara":2, "ruokalaji": 33, "reseptiid": 1}) except sqlite3.Error: virheet += 1 if virheet: con.rollback() #jos virheitä niin perutaan muutokset else: con.commit() # kommitoidaan kaikki edellä tehdyt muutokset. Jos tätä ei tehdä niin mikään edellä tehdyistä ei jää voimaan # Sama kuin edellä, mutta hyödynnetään autoincrement-kenttiä. Nyt lisääminen onnistuu sql = '''INSERT INTO ruokalaji (Nimi, Kuvaus) VALUES (:nimi, :kuvaus ) ''' # ruokalajien nimien on oltava uniikkeja joten tätä samaa ei voi lisätä useampaan kertaan nimi = 'Salaiset ruuat' kuvaus = 'Ihan oma herkut' virheet = 0 try: cur.execute( sql, {"nimi":nimi, "kuvaus":kuvaus}) except sqlite3.Error: virheet += 1 sql = '''INSERT INTO resepti (Nimi, Kuvaus, henkilomaara, ruokalajiid) VALUES (:nimi, :kuvaus, :henkilomaara, :ruokalaji) ''' nimi = 'Salainen ruoka' kuvaus = 'namnam' ruokalaji = cur.lastrowid #haetaan edellisen kyselyn lastrowid try: cur.execute( sql, {"nimi":nimi, "kuvaus":kuvaus, "henkilomaara":2, "ruokalaji": ruokalaji}) except sqlite3.Error: virheet += 1 if virheet: con.rollback() #jos virheitä niin perutaan muutokset else: con.commit() # kommitoidaan kaikki edellä tehdyt muutokset. Jos tätä ei tehdä niin mikään edellä tehdyistä ei jää voimaan except sqlite3.Error: errors = "" for err in sys.exc_info(): errors = errors + str(err) return "Tietokanta ei aukea : " + errors finally: con.close() return render_template('reseptit.html', reseptit=reseptit, ruokalajit=ruokalajit, ruokareseptit=ruokareseptit, ruokareseptit_all=ruokareseptit_all)