Садржај
3.0 SQL: Промена садржаја базе
3.2 SQL: Ажурирање података у табелама
3.3 SQL: Брисање података из табела
7.0 Библиотека Flask - пројектни задатак

Постављање упита

Да би могао да се постави упит, потребно је креирати објекат који се назива курсор. То се ради тако што се над објектом конекције позове метод cursor(). На пример,

import sqlite3

db_conn = sqlite3.connect(...)
cur = db_conn.cursor()
...
db_conn.close()

Упит затим можемо да извршимо позивом методе execute на креираном курсору. Параметар је ниска која садржи текст упита на језику SQL. На пример, унос новог ученика у табелу може да се изврши на следећи начин:

cur.execute("INSERT INTO ucenik (ime, prezime, razred, odeljenje)" +
            "VALUES ('Петар', 'Петровић', 1, 1)");

Поделу упита на две ниске смо урадили само прегледности ради.

Уколико се ради о неком упиту који врши измене над базом (INSERT, UPDATE, DELETE), након извршавања упита (или неколико таквих упита) потребно је над конекцијом позвати методу commit којом се измене трајно уписују у базу. Текст целокупног програма који уписује новог ученика тада гласи овако.

import os
import sqlite3

db_conn = sqlite3.connect(os.path.join(os.getcwd(), 'dnevnik.db'))
cur = db_conn.cursor()
cur.execute("INSERT INTO ucenik (ime, prezime, razred, odeljenje)" +
            "VALUES ('Петар', 'Петровић', 1, 1)");
db_conn.commit()
db_conn.close()

Ако се методом execute извршава упит читања података из базе (упит SELECT), тада је повратна вредност позива методе execute резултујућа табела, смештена у специјализованој структури података коју можемо посматрати као листу врста, што значи да помоћу петље for можемо обрађивати једну по једну врсту. Свака врста је уређена торка. Размотримо наредни програм који чита и исписује имена и презимена свих ученика.

import os
import sqlite3

db_conn = sqlite3.connect(os.path.join(os.getcwd(), 'dnevnik.db'))
cur = db_conn.cursor()
res = cur.execute("SELECT ime, prezime FROM ucenik");
for row in res:
    print(row[0], row[1])
db_conn.close()

Променљива res садржи резултат упита, док променљива row садржи редом једну по једну врсту тог резултата. Врсте су уређени парови (двочлане торке) и име и презиме се издвајају из њих коришћењем индексног приступа (row[0] ће бити име, а row[1] презиме). Читљивији код се може добити ако се петља реализује на следећи начин:

for ime, prezime in res:
    print(ime, prezime)

Могуће је подесити и да врсте резултата упита буду речници (а не уређене торке), тако да се подацима унутар врсте може приступити било на основу редног броја, било на основу назива колоне. Након повезивања са базом, отвореној конекцији је потребно променити атрибут row_factory, чији је параметар функција која трансформише сваку врсту пре него што јој се приступи. Да би се торка трансформисала у речник, довољно је вредност тог параметра поставити на функцију sqlite3.Row.

...
db_conn = sqlite3.connect(os.path.join(os.getcwd(), 'dnevnik.db'))
db_conn.row_factory = sqlite3.Row
cur = db_conn.cursor()
res = cur.execute("SELECT ime, prezime FROM ucenik");
for row in res:
    print(row["ime"], row["prezime"])
db_conn.close()

Нагласимо још једном да је у реалним програмима у склопу упита SELECT увек пожељно експлицитно навести називе и редослед колона које се читају из базе. Тај редослед се после користи и у петљама које обрађују резултате упита, па ако се он упари са оним наведеним након кључне речи SELECT, тада нема опасности да скрипт престане да ради ако се структура табела у бази мало промени (нпр. дода се нека нова колона).

Резултат упита се чува у специјалној структури података кроз коју можемо да итерирамо помоћу петље for. Та структура података није листа и сасвим је могуће да се врше разне оптимизације које доводе до тога да се цела табела резултата никада не чува истовремено у меморији.

Ако нам итерирање кроз редове резултата није довољно, већ желимо да се кроз резултат крећемо слободније, листу торки у којој се чува цео резултат можемо да добијемо коришћењем метода fetchall над курсором над којим је извршен упит. Слично, метод fetchone враћа наредну врсту у резултату претходно извршеног упита.

(Created using Swinx, RunestoneComponents and PetljaDoc)
© 2022 Petlja
A- A+