nocmatic / prevozi

Pri predmetu Osnove podatkovnih baz bova izdelala aplikacijo, na katero bodo lahko uporabniki dodali prevoze, ki jih ponujajo, ocenili uporabnika,
MIT License
0 stars 1 forks source link

Neumno vprašanje #7

Open PavesicL opened 7 years ago

PavesicL commented 7 years ago

V aplikaciji imava nek default bootstrapov global header (z opcijami BLOG/CONTACTS/HOME...), ki ga neznam pobrisat/umaknit. Zdi se mi, da je vse skupaj nekje v main.css, ampak ne najdem kje. Kaj v resnici je to in kako se pobrise?

jaanos commented 7 years ago

Glavo imata v base.html.

Še to: ko poženem aplikacijo, dobim:

  File "Prevozi.py", line 91
    else: 
         ^
IndentationError: unindent does not match any outer indentation level

Kot vidim, uporabljata v Prevozi.py tako presledke kot tabulatorje, kar zna zmesti Python (jaz imam različico 3.5.2 - mogoče se kakšna novejša različica bolje znajde s tem). Zato svetujem, da tega ne mešata in uporabljata samo presledke ali samo tabulatorje - najlažje bo, če vse tabulatorje nadomestita s štirimi presledki. Poleg tega pazita tudi, kam dasta dokumentacijo funkcij - ta naj bo za začetkom funkcije, zamaknjena kot preostala koda v funkciji:

@route('/signup', method= "POST")
def signup():
    """Registrira novega uporabnika. Preveri ce uporabnisko ime ze obstaja, ce se gesli ujemata, ce sta geslo, uporabnisko ime, telefon dovolj dolgi. Ce je vse ok, hashano geslo 
    in podatke o uporabniku shrani v tabelo uporabnik v bazi. Nastavi piskotek in prikaze glavno stran."""

    uporabnisko_ime = bottle.request.forms.uporabnisko_ime 
    ...

Da bo aplikacijo mogoče zagnati, poskrbita še za pravice na bazi in datoteko auth_public.py s podatki za prijavo - glejta #4.

PavesicL commented 7 years ago

Popravil sem presledke, zdaj bi moralo biti ok. Glede pravic na bazi mislim da sem vse nastavil pravilno, nisem pa preprican kako se da to preveriti.

jaanos commented 7 years ago

Manjka še pravica uporabe števca (tako se nisem mogel registrirati) - najlažje to naredita za vse obstoječe števce tako:

GRANT USAGE ON ALL SEQUENCES IN SCHEMA public TO javnost;

Pravice tabel in števcev lahko v phpPgAdminu preverita tako, da klikneta na zavihek Privileges.

Sicer pa svetujem, da za tuje ključe povsod uporabljata ID-je - pri uporabnikih jih že imata, tako da jih uporabita tudi v tabelah narocanje in prevoz. ID-je dodajta še pri krajih - tako bo npr. mogoče delati popravke samo v tabeli kraj, ne da bi bilo za to potrebno popravljati še vnosov v tabeli prevoz.

PavesicL commented 7 years ago

Sem popravil in dodal id-je v tabelah, ali naj so reference tujih ključev iz drugih tabel raje na id?

jaanos commented 7 years ago

Tako, ja, vsi tuji ključi naj kažejo na ID-je.

PavesicL commented 7 years ago

Še to, ali je še kakšen problem, ki naj ga popravim preden oddava aplikacijo?

jaanos commented 7 years ago

Kot rečeno, tudji ključi v tabeli prevoz naj kažejo na ID-je uporabnikov in krajev - pri iskanju bo potem imena seveda treba dobit z JOIN. Svetujem tudi, da iskalnik išče tudi po delih imen - to lahko dosežete tako, da pred in po vnesenemu imenu postavita še %, npr. zacetni_kraj ILIKE '%%'||%s||'%%' (procenti so podvojeni, ker imajo poseben pomen za psycopg2, npr. za %s).

Ko poskušam dodati prevoz, dobim napako - najbrž bo treba poskrbeti za ustrezno pretvorbo tipov (morda je to drugače v novejših različicah Pythona - jaz uporabljam 3.5.2):

  File "Prevozi.py", line 141, in glavna_stran
    if zacetek < datetime.now():
TypeError: unorderable types: str() < datetime.datetime()

Sicer pa svetujem, da uporabite kakšen HTML/JS gradnik za izbiro datuma in ure (v bazo ju lahko vpišete tudi v obliki YYYY-mm-dd HH:MM:SS). Poskrbita še za preusmeritev ob uspešnem dodajanju prevoza.

PavesicL commented 7 years ago

if pogoj, ki daje napako sem pobrisal, ker za to, da sta začetek in konec kasneje od datetime.now() poskrbi že koledar v template-u sam, vsaj pri meni. (V resnici koledat ne dovoli objave prevoza, ki se začne pred zadnjim refreshom strani - good enough.)

Dodal sem id-je in reference na id-je v vse tabele. To izjemno zakomplicira poizvedbe v bazi - kaj je dobra lastnost takega načina?

jaanos commented 7 years ago

Prednost pristopa z ID-ji je ta, da se podatki ne podvajajo, kar je koristno tako s stališča porabe prostora kot tudi integritete podatkov. Tako se ime vsakega mesta shrani samo enkrat, pri vsakem prevozu pa je shranjen samo njegov ID (najverjetneje bo to 32-bitna številka - torej 4 bajti, kar je manj kot večina imen mest). Podobno, če bi hotela katero ime mesta popraviti, lahko to sedaj storita enostavno tako, da popravita vnos v ustrezni tabeli - ni potrebe, da popravljata še vse reference.

Cena takega pristopa je seveda v nekoliko kompleksnejših poizvedbah, a v resnici so pogosto take poizvedbe celo učinkovitejše (tako ali tako pa so velikokrat take poizvedbe potrebne, saj potrebujeta več podatkov iz pridruženih tabel). Če npr. iščeta prevoz iz krajev, ki vsebujejo vneseni niz, bo baza najprej poiskala ID-je teh krajev v (manjši) tabeli mest, nato pa za vsakega poiskalo ustrezne prevoze (kar se zgodi hitro, saj se na tujih ključih zgradi indeks). Nasprotno, če bi imena krajev imela kar pri prevozih, bi morala baza za delne poizvedbe preiskati celotno (večjo) tabelo.

Sicer pa ni potrebno, da pri vsakem JOIN naredita svoj SELECT - večinoma se da delati neposredno s tabelami (praktično vedno, če nimata kakšnih GROUP BY ali LIMIT v podpoizvedbi). Tako bi lahko iskanje prevozov bolj berljivo zapisala tako:

SELECT prevoz.id, zacetek, konec, prosta_mesta,
 username AS objavil, zacetni.ime AS zacetni_kraj,
 koncni.ime AS koncni_kraj FROM prevoz
 JOIN kraj AS zacetni ON zacetni_kraj = zacetni.id
 JOIN kraj AS koncni ON koncni_kraj = koncni.id
 JOIN uporabnik ON objavil = uporabnik.id
WHERE prosta_mesta >= %s
 AND zacetni.ime ILIKE '%%'||%s||'%%'
 AND koncni.ime ILIKE '%%'||%s||'%%'

Če hočeta v Pythonu napisati niz, ki obsega več vrstic, ga obdajta s """ (tj., tri dvojne navednice na vsaki strani).