CDS104-Databases-and-Data-P.../code/online-part-2a/Zoo_Task_CRUD_Operations.ipynb
2025-05-18 19:12:55 +02:00

290 lines
9.2 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Zooverwaltung\n",
"\n",
"In diesem Beispiel wird ein System zur Verwaltung von Zoos implementiert. Hier gibt es eine Tabelle für Personen (TierplegerInnen) und eine Tabelle für Tiere. Eine Person kann mehrere Tiere betreuen, und ein Tier gehört einer Person.\n",
"\n",
"Im ersten Teil sollen Sie 5 Funktionen schreiben, die es Ihnen erlaubt, Personen anzulegen, zu lesen (einzeln und als Liste), zu ändern und zu löschen. Die Tabellen sind dabei vorgegeben und Sie finden im Notebook einige Testaufufe."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import psycopg2\n",
"import psycopg2.extras"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"# Verbindung aufbauen\n",
"# TODO: hier müssen Ihre Verbindungsdaten eingetragen werden\n",
"# TODO: ggf. müssen Sie auch den Namen der Datenbank anpassen oder eine leere Datenbank 'zoo' anlegen\n",
"\n",
"conn = psycopg2.connect(\n",
" host=\"localhost\",\n",
" port=5432,\n",
" dbname=\"postgres\",\n",
" user=\"postgres\",\n",
" password=\"postgres\",\n",
")\n"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"# Diese Zelle löscht die Tabellen, falls sie bereits existieren, und legt sie neu an\n",
"sql = \"\"\"\n",
" DROP TABLE IF EXISTS animals;\n",
" DROP TABLE IF EXISTS zookeepers;\n",
"\n",
" CREATE TABLE zookeepers (\n",
" id SERIAL PRIMARY KEY,\n",
" name VARCHAR(255) NOT NULL,\n",
" email VARCHAR(255),\n",
" specialty VARCHAR(255)\n",
" );\n",
"\n",
" CREATE TABLE animals (\n",
" id SERIAL PRIMARY KEY,\n",
" name VARCHAR(255) NOT NULL,\n",
" species VARCHAR(255) NOT NULL,\n",
" zookeeper_id INTEGER,\n",
" FOREIGN KEY (zookeeper_id) REFERENCES zookeepers(id)\n",
" );\n",
"\"\"\"\n",
"\n",
"# SQL ausführen\n",
"cur = conn.cursor()\n",
"cur.execute(sql)\n",
"conn.commit()\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# TODO: Implementieren Sie hier die CRUD-Operationen für Zookeeper\n",
"\n",
"# TODO: Tierpleger anlegen, liefert die ID des neuen Tierpflegers zurück\n",
"def create_zookeeper(name, email, specialty):\n",
" pass\n",
"\n",
"# TODO: Tierpfleger nach ID lesen, Tupel zurückgeben\n",
"def read_zookeeper(id):\n",
" pass\n",
"\n",
"# TODO: Alle Tierpfleger lesen, liefert eine Liste von Tupeln zurück (nach ID sortiert)\n",
"def read_all_zookeepers():\n",
" pass\n",
"\n",
"# TODO: Tierpfleger aktualisieren\n",
"def update_zookeeper(id, name, email, specialty):\n",
" pass\n",
"\n",
"# TODO: Tierpfleger per ID löschen\n",
"def delete_zookeeper(id):\n",
" pass"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Tests - diese sollten alle erfolgreich durchlaufen werden und nicht verändert werden\n",
"\n",
"# john = (\"John Doe\", \"john@example.com\", \"Elephants\")\n",
"# jane = (\"Jane Doe\", \"jane@example.com\", \"Giraffes\")\n",
"\n",
"# id = create_zookeeper(*john)\n",
"# id2 = create_zookeeper(*jane)\n",
"\n",
"# assert read_zookeeper(id) == (id, *john)\n",
"# assert read_zookeeper(id2) == (id2, *jane)\n",
"\n",
"# john = (\"John Smith\", \"john2@example.com\", \"Zebras\")\n",
"# update_zookeeper(id, *john)\n",
"# assert read_zookeeper(id) == (id, *john)\n",
"\n",
"# all_zookeepers = read_all_zookeepers()\n",
"# assert len(all_zookeepers) == 2\n",
"# assert all_zookeepers[0] == (id, *john)\n",
"# assert all_zookeepers[1] == (id2, *jane)\n",
"\n",
"# delete_zookeeper(id)\n",
"# delete_zookeeper(id2)\n",
"# assert read_zookeeper(id) == None\n",
"# assert read_zookeeper(id2) == None\n",
"\n",
"# all_zookeepers = read_all_zookeepers()\n",
"# assert len(all_zookeepers) == 0"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Nutzung eines ORMs\n",
"\n",
"Wie wir sehen, ist das manuelle Erstellen von Zugriffsfunktionen auf die Datenbank sehr aufwändig. Daher gibt es sogenannte Object-Relational-Mapper (ORMs), die uns diese Arbeit abnehmen. Ein bekanntes ORM für Python ist `SQLAlchemy`. Im zweiten Teil des Notebooks werden wir sehen, wie mit `SQLAlchemy` Daten eingefügt und gelesen werden können.\n",
"\n",
"Da Sie Anaconda nutzen, sollte `SQLAlchemy` bereits installiert sein. Falls nicht, können Sie es mit `conda` installieren.\n",
"\n",
"Wenn man `SQLAlchemy` verwendet, definiert man zunächst eine Klasse, die die Tabelle repräsentiert. Hier sind diese Klassen bereits für Personen und Tiere definiert. Sie können sich die Klassen ansehen, um zu verstehen, wie Tabellen in `SQLAlchemy` definiert werden."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"## Nutzung von SQLAlchemy\n",
"from sqlalchemy import create_engine, Column, Integer, String, ForeignKey\n",
"from sqlalchemy.orm import Session, relationship, declarative_base\n",
"\n",
"Base = declarative_base()\n",
"\n",
"class Zookeeper(Base):\n",
" __tablename__ = 'zookeepers'\n",
" id = Column(Integer, primary_key=True)\n",
" name = Column(String, nullable=False)\n",
" email = Column(String)\n",
" specialty = Column(String)\n",
" animals = relationship(\"Animal\", back_populates=\"zookeeper\")\n",
"\n",
"class Animal(Base):\n",
" __tablename__ = 'animals'\n",
" id = Column(Integer, primary_key=True)\n",
" name = Column(String, nullable=False)\n",
" species = Column(String, nullable=False)\n",
" zookeeper_id = Column(Integer, ForeignKey('zookeepers.id'))\n",
" zookeeper = relationship(\"Zookeeper\", back_populates=\"animals\")\n",
"\n",
"# TODO: Verbingung zur Datenbank herstellen\n",
"engine = create_engine('postgresql://IHR_POSTGRES_USER:IHR_POSTGRES_PASSWORD/zoo')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Anlegen und Abfragen von Objekten in SQLAlchemy\n",
"\n",
"In diesem Teil sollen Sie 2 Personen und 5 Tiere anlegen und dann alle Personen und Tiere abfragen. Sie können sich an den Beispielen orientieren, die im Notebook gegeben sind.\n",
"\n",
"Ein kurzes und übersichtliches Tutorial zur Nutzung von `SQLAlchemy` finden Sie hier:\n",
"\n",
"https://docs.sqlalchemy.org/en/20/orm/session_basics.html\n",
"\n",
"Relevant sind vor allem folgende Abschnitte:\n",
"\n",
"https://docs.sqlalchemy.org/en/20/orm/session_basics.html#opening-and-closing-a-session\n",
"https://docs.sqlalchemy.org/en/20/orm/session_basics.html#adding-new-or-existing-items\n",
"https://docs.sqlalchemy.org/en/20/orm/session_basics.html#querying"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# TODO: zwei Zookeeper anlegen\n",
"with Session(engine) as session:\n",
" john = ...\n",
" jane = ...\n",
"\n",
" session.add(...)\n",
"\n",
" session.commit()\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# TODO: Alle Zookeeper ausgeben\n",
"with Session(engine) as session:\n",
" ..."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# TODO: 3 Elefanten anlegen, die John betreut\n",
"with Session(engine) as session:\n",
" ...\n",
"\n",
"# TODO: 2 Giraffen anlegen, die Jane betreut\n",
"with Session(engine) as session:\n",
" ..."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Liste aller Tiere mit ihren Pflegern ausgeben:\n",
"with Session(engine) as session:\n",
" ...\n",
"\n",
"# Beispielausgabe:\n",
"#\n",
"# ----------------------------------------\n",
"# | Babar | Elephant | John Doe |\n",
"# | Dumbo | Elephant | John Doe |\n",
"# | Hathi | Elephant | John Doe |\n",
"# | Melman | Giraffe | Jane Doe |\n",
"# | Gloria | Giraffe | Jane Doe |\n",
"# ----------------------------------------\n"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "code (3.13.2)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.13.3"
}
},
"nbformat": 4,
"nbformat_minor": 2
}