Kako iz programa do baze

Kako iz programa do baze

Avtor: Matija Lokar

Kako do podatkov v bazi

  • Podatke hranimo v bazi
  • S pomočjo jezika SQL "enostavno" dobimo ustrezne podatke
  • Sedaj pa bi s temi podatki radi še kaj naredili
  • Narisali, poiskali optimalno podzaporedje, ...
  • Torej:

    • Kako iz baze dobiti podatke, da jih uporabimo v izbranem programskem jeziku
  • Ali tudi, če počnemo "navadne" zadeve?

    • Torej take, ki so bolj ali manj enostavno izvedljive kar s SELECT (in ostalo kramo stavkov v SQL)
    • Da! Zakaj?

      • SQL je za običajnega zemljana "pretežek"
      • Potrebujemo gumbke, vnosna polja, ...
      • Podatki morajo biti prikazani "lepo"

Baza program

  • Ustrezen ukaz, s katerim se povežemo z bazo

    • Kot pri delu z datotekami "odpremo" datoteko
    • Tu se še "logiramo", ...
  • Ustrezen ukaz v našem programskem jeziku s katerim bazi posredujemo ukaz v jeziku SQL (običajno je ta ukaz SQL v obliki niza)
  • Baza našemu programu vrne podatke

    • Kot bi "brali"
  • Podatke ustrezno preoblikujemo za potrebe programa

    • Kot npr. int(…) ...
  • V ta namen imamo običajno ustrezne razrede, ki "to znajo" (objekti, gradniki, komponente, ...)

Delphi

  • Imamo bazo. Iz nje pridobimo podatke. To nam omogočajo objekti tipa ADOTable in ADOQuery . To so podatki v »surovi« obliki. Da poenotimo pogled na vse in jih morebiti še ustrezno predelamo, te objekte povežemo z objekti tipa DataSource , ki podatke oblikuje na tak način, da jih lahko prikažemo in obdelujemo s pomočjo objektov vrste Data Controls (DBGrid , DBEdit , …), ki so objekti za vizualni prikaz podatkov.
(shema.jpg)

C# in baze

  • Vsi programski jeziki se "pogovarjajo" z relacijskimi bazami preko podatkovnega vmesnika.
  • Programje, ki omogoča komunikacijo med programom in RDBMS.
  • Programje za C#: ADO.NET
  • Ustrezni imenski prostori

    • System.Data
    • System.Data.OleDb
    • System.Data.SqlClient
    • ...

Python in baze

(shema1.jpg)
  • Različni DBMS

    • Različne knjižnice
  • Določena so pravila, kako se morajo obnašati ti razredi

    • DB-API 2.0
  • Primeri

    • import MySQLdb # za MySQL
    • import sqlite3 # za "vgrajeni" RDBMS
    • import psycopg2 # za PostgerSQL
  • Pogosto

    • import sqlite3 as dbapi # in potem delamo kar z dbapi

"Glavni igralci"

  • Podatkovni vir: izvor podatkov

    • Baze
    • Pa tudi: datoteke XML, ...
  • Povezava do podatkovnega vira

    • Ustrezen razred, ki vsebuje podatke o tem, kje je podatkovni vir in kako se do njega dostopa
    • pov = dbapi.connect(povezovalniNiz)
  • Kazalec (cursor)

    • V terminologiji baz podatkov prostor v pomnilniku, ki vsebuje podatke, ki jih dobimo iz tabel v bazi
    • Objekt, ki predstavlja "sla" maed programom in bazo
    • cursor = pov.cursor()
  • Podatki

    • "Tabele", ki jih vrne ukaz
    • Predstavitev podatkov v programu
    • cursor.execute(ustrezenSQLukaz)

Primer

import psycopg2 as dbapi
# Povežimo se na obstoječo bazo
conn = dbapi.connect("dbname=test user=postgres")
# Odpremo kazalec
cur = conn.cursor()
# Izvedemo ukaz – naredimo tabelo
cur.execute("CREATE TABLE test (id serial PRIMARY KEY, num integer, data varchar);")
# podatke vstavimo v tabelo
cur.execute("INSERT INTO test (num, data) VALUES (%s, %s)", (100, "abc'def"))
# sedaj preberimo nazaj
cur.execute("SELECT * FROM test;")
rezultat  = cur.fetchone() #hočemo le eno vrstico
print(rezultat) # izpiše se (1, 100, "abc'def")
# poskrbimo, da so spremembe v bazi trajne
conn.commit()
# Zapremo povezave z bazo
cur.close()
conn.close()

Podatkovni viri - knjižnice

Povezava

  • Prvi objekt, ki ga potrebujemo
  • Osnovna povezava do podatkovnega vira

    • Poskrbi tudi za upo. ime, geslo …
  • Potrebujejo povezovalni niz (connection string)

Povezovalni niz

  • Značilen za vsak posamezen podatkovni vir
  • Informacije o mestu vira, uporabniku, …
  • Običajno vsebuje več delov, ločenih s ; ali presledki ali …
  • Primeri

    • SQL Server:

      Data Source=myServerAddress;Initial Catalog=myDataBase;User
      Id=myUsername;Password=myPassword;
  • MySQL:

    Server=myServerAddress;Database=myDataBase;Uid=myUsername;Pwd=myPassword;
  • SQL Server Compact Edition:

    Data Source=MyData.sdf;Persist Security Info=False;
  • Odličen vir:

  • Z bazo SQLite3 ni težav (če ne kompliciramo ;-) )!

    • Povezovalni niz je le pot do datoteke (ker je cela baza le ena datoteka)

Povezava do baze

  • import sqlite3 as dbapi
  • imeBaze = 'banka.db'
  • baza = dbapi.connect(imeBaze) #
    povezava do baze
  • cur = baza.cursor()
  • In sedaj lahko delamo z bazo

Izvajanje ukazov

  • Sestavimo ukaz

    • ukazSQL = "SELECT * FROM BBC WHERE name Like 'S%'"
  • Izvedemo ukaz

    • cur.execute(ukazSQl)
  • Seveda bi lahko tudi

    • cur.execute("SELECT * FROM BBC WHERE name Like 'S%'")
  • Obdelamo rezultate

    • Različne oblike fetchXXX()
    • rez = cur.fetchall() # dobimo seznam naborov
    • rez = cur.fetchone() # nabor
  • Ali pa kar z

    • for vrstica in cur # posamezna vrstica je nabor
  • Več: http://docs.python.org/library/sqlite3.html

Zgled

  • Del baze nobelovih nagrajencev
  • Nobel_baza.py

import sqlite3 as dbAPI

# Stavki, s katerimi naredimo podatkovno zbirko

STAVKI_CREATE_TABLE = """
----------------------------------------------------------------------
-- dobitniki Nobelovih nagrad
----------------------------------------------------------------------

CREATE TABLE IF NOT EXISTS nobel (
  yr INTEGER,
  subject TEXT,
  winner TEXT
);

"""

nagrajenci = [
(2008 ,'Chemistry',   'Martin Chalfie'),
(2008 ,  'Chemistry',   'Osamu Shimomura'),
...
(1998 ,  'Physics',   'Daniel C. Tsui')
]

# ====================================#

def vpišiNagrajenca(cur, **kwargs): #uporaba poimenovanih parametrov
    """Vpiši osebo z danimi podatki."""
    cur.execute("""INSERT INTO nobel(yr, subject, winner)
                   VALUES (:yr, :subject, :winner)""",
                kwargs)
    return cur.lastrowid

# --------- Glavni program ----------
# Priklopimo se na podatkovno bazo, ki je shranjena
# v datoteki Nobel.db

db = dbAPI.connect('nobel.db')
c = db.cursor()

# Naredimo tabelo, če je še ni
c.execute(STAVKI_CREATE_TABLE)

#Vstavljanje podatkov v bazo

# Vnesemo podatke

for x in nagrajenci :
    vpišiNagrajenca(c,
                yr="%d" % x[0],
                subject="%s" % x[1],
                winner="%s" % x[2])

# Dejansko zapišemo v bazo
db.commit()

# Izberemo vse nagrajence od 2006 dalje
c.execute("SELECT * FROM nobel WHERE yr > 2005")

# Gremo vrstico po vrstico čez rezulate SELECT
for vrstica in c:
    print("Nobelovec: %s" % str(vrstica))

# Kurzorja ne potrebujemo več, ga zapremo
c.close()
# Tudi povezave do baze ne
db.close()

Zgled

  • bankaPredavanja.py
  • Nekaj komentarjev:

    • STAVKI_CREATE_TABLE je niz, ki vsebuje več ukazov SQL, pozor na
    • c.executescript(STAVKI_CREATE_TABLE)

      • Ker je v nizu več ukazov!
      • c.exectute(samoEnUkazSQL)
    • Če boste program zagnali večkrat, bo javil napako – ker podatke dodajamo in s tem kršimo pravilo enotnega ključa
    • c.description – dejansko potrebujemo le prvo vrednost vsakega nabora, ostalih 6 (vsi None) so zaradi združljivosti nazaj
    • V programu delamo vstavljanje s pomočjo slovarjev

      • Izogib "napadom SQLInjection"
0%
0%