10.5 Python ↔ PostgreSQL (psycopg2)

Tavs šīs stundas izaicinājums: Savienot Python kodu ar PostgreSQL datubāzi un izpildīt drošus parametrizētus vaicājumus.

SR 2.4.11. Lieto standartizētas bibliotēkas un API SR 3.2.5. Drošības riski

Teorija: psycopg2 — Python ↔ PostgreSQL tilts

psycopg2 ir Python bibliotēka, kas savieno tavu kodu ar PostgreSQL datubāzi. Instalācija: pip install psycopg2-binary.

import psycopg2

conn = psycopg2.connect(
    host="localhost",
    database="spele",
    user="postgres",
    password="tavs_parole"
)
cur = conn.cursor()

# DROŠA parametrizēta vaicājuma forma — %s ir TIKAI vietturis
cur.execute("SELECT * FROM speletaji WHERE punkti > %s", (100,))
for rinda in cur.fetchall():
    print(rinda)

conn.commit()  # apstiprina izmaiņas
cur.close()
conn.close()

⚠ DROŠĪBA: NEKAD nelieto string formatēšanu (f"...{x}...") SQL vaicājumos — tas ir SQL injekcijas uzbrukums!

1. uzdevums: Pirmais savienojums

Pārbaudi, ka Python var pieslēgties datubāzei.

Izpildes soļi:

  1. Termināli: pip install psycopg2-binary
  2. Izveido failu db_test.py: importē psycopg2, savienojas, izpilda SELECT NOW(), izvada laiku.
  3. Izveido .env failu paroles glabāšanai (NEPUSH GitHub-ā!).
  4. Pievieno .env savam .gitignore failam.

2. uzdevums: CRUD ar Python

Ieprogrammē funkcijas datu pievienošanai un nolasīšanai.

Izpildes soļi:

  1. Funkcija pievienot_speletaju(vards) — INSERT ar parametriem un RETURNING id.
  2. Funkcija iegut_visus() — SELECT un atgriež sarakstu.
  3. Funkcija atjauninat_punktus(id, jaunie) — UPDATE ar WHERE.
  4. Funkcija dzest_speletaju(id) — DELETE ar WHERE.
  5. Pārbaudi visas četras funkcijas — datubāzē jāparādās izmaiņām.

3. uzdevums: Drošība un commit/rollback

Demonstrē transakcijas un drošību pret SQL injekciju.

Izpildes soļi:

  1. Eksperiments: ievadi spēlētāja vārdu kā '); DROP TABLE speletaji; --. Vai ar parametriem tas nodara skādi? (Nē — drošs!)
  2. Mēģini izpildīt 5 INSERT operācijas vienā transakcijā, bet pirms commit() piesauc raise Exception().
  3. Pieliec conn.rollback() — pārbaudi datubāzi, vai izmaiņas atcēlās.
  4. Lieto with conn: kontekstu — automātiska commit/rollback.

Papildus uzdevums: RealDictCursor

Atgriež rezultātus kā vārdnīcas, nevis kā kortežus.

Izpildes soļi:

  1. from psycopg2.extras import RealDictCursor
  2. cur = conn.cursor(cursor_factory=RealDictCursor)
  3. Tagad cur.fetchall() atgriež [{'id': 1, 'vards': 'Anna', ...}, ...]
  4. Pārveido savas funkcijas, lai lieto vārdnīcas (skaidrāks kods).

Biežākās kļūdas

Koda piemērs

import psycopg2
from psycopg2.extras import RealDictCursor

with psycopg2.connect(
    host="localhost", database="spele",
    user="postgres", password="parole"
) as conn:
    with conn.cursor(cursor_factory=RealDictCursor) as cur:
        # DROŠA INSERT
        cur.execute(
            "INSERT INTO speletaji (vards) VALUES (%s) RETURNING id",
            ("Anna",)
        )
        jauns_id = cur.fetchone()["id"]
        print(f"Pievienots ar id = {jauns_id}")

        cur.execute("SELECT * FROM speletaji ORDER BY id DESC LIMIT 3")
        for r in cur.fetchall():
            print(r["vards"], r["punkti"])
Pievienots ar id = 12
Anna 0
Marta 200
Eva 145
⬅ Iepriekšējā stunda Nākamā stunda ➡