{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Datenbankverbindungen mit Python\n", "\n", "In diesem Notebook lernen wir, wie wir: \n", " * eine Verbindung zur Datenbank herstellen\n", " * SQL Ausführen (und Parameter aus Python nutzen)\n", "\n", "Vorraussetzungen hierfür sind:\n", " * Grundkenntnisse Python\n", " * Grundkenntnisse SQL\n", " \n", "Die Methoden die für den Zugriff auf die Datenbank nötig sind, sind in der Python Database API Specification v2 [PEP 249](https://www.python.org/dev/peps/pep-0249/) beschrieben.\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Eine Verbindung zur Datenbank herstellen\n", "\n", "Die Datenbankverbindung wird über das Modul der Datenbank aufgebaut. Dieses Modul verfügt über eine `connect( parameters... )`-Methode. Die genauen Parameter, die eine Datenbank für die Verbindung benötigt, kann jedes Datenbank-Modul selbst festlegen. \n", "\n", "In unseren Beispiel verwenden wir eine Sqlite3-Datenbank. Der Parameter `:memory:` erzeugt eine Datenbank im Hauptspeicher. Diese Datenbank ist sehr schnell erstellt, aber dafür nicht persistent. Zum erproben der Verbindungsfunktionen ist dies jedoch vollkommen ausreichend. " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%run Datenbankzugriff_Util.ipynb # import zu Überprüfung der Übungen\n", "\n", "# Verbindung mit der Datenbank herstellen\n", "import sqlite3\n", "conn = sqlite3.connect(':memory:')\n", "\n", "\n", "#import mysql.connector\n", "#conn = mysql.connector.connect(\n", "# host=\"localhost\",\n", "# user=\"yourusername\",\n", "# password=\"yourpassword\",\n", "# database=\"mydatabase\"\n", "#)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## SQL Ausführen\n", "\n", "SQL-Statements werden mithilfe eines Cursors ausgeführt. Ein Cursor kann auch DML- oder DDL-Anfragen ausführen. Bei DQL-Abfragen können Datensätze mit fetchall() direkt geladen werden. " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# DDL\n", "cur = conn.cursor()\n", "cur.execute('''CREATE TABLE emp(id NUMBER, name VARCHAR(255), sal NUMBER)''')\n", "cur.close()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# DML\n", "c= conn.cursor()\n", "# Daten einfuegen\n", "c.execute(\"INSERT INTO emp VALUES (1, 'Smith', 3200)\")\n", "c.execute(\"INSERT INTO emp VALUES (2, ?, 2800)\", [(\"Adams\")])\n", "c.executemany(\"INSERT INTO emp VALUES (?, ?, ?)\", \n", " [(3, \"King\", 5200), (4,\"Johnson\", 3400)])\n", "conn.commit();" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Abfrage von Daten (SELECT)\n", "c.execute('SELECT * FROM emp')\n", "result = c.fetchall()\n", "for x in result:\n", " print(x[1])\n", "c.close()\n", " \n", " \n", "print(\"Der Zugriff über den Spaltennamen ist auch möglich\")\n", "conn.row_factory = sqlite3.Row \n", "c= conn.cursor()\n", "c.execute('SELECT * FROM emp')\n", "result = c.fetchall()\n", "for x in result:\n", " print(x['name'])\n", "c.close() \n", " " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# fetchone bis None\n", "print(\"Für größere Datenmengen sollte man auf fetchall aus performencegründen verzichten. \")\n", "c= conn.cursor()\n", "c.execute('SELECT * FROM emp')\n", "row = c.fetchone()\n", "while row != None:\n", " print(row['name'])\n", " row = c.fetchone()\n", "\n", "c.close()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Übung: Datensätze einfügen\n", "\n", "Fügen Sie folgenden Datensatz in die Tabelle emp der Datenbank ein.\n", "\n", "| ID | Name | Salary | \n", "|------|------------|--------|\n", "| 10 | May | 4100 | " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#TODO: hier Datensatz einfügen\n", "\n", "\n", "\n", "check(conn)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Fehlerbehandlung\n", "Bei Datenbankabfragen kann es immer zu Fehlern kommen, diese sollten behandelt werden." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from sqlite3 import OperationalError\n", "\n", "cur = conn.cursor()\n", "try:\n", " cur.execute('SELECT * FROM non_existing_emp')\n", "except OperationalError as e:\n", " print(\"Bei der Datenbankabfrage ist ein Fehler aufgetreten: \" + str(e));\n", "cur.close();" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Integration von Python in SQLite\n", "\n", "Da die Datenbankengine SQLite komplett in Python integriert ist, lassen sich Python-Funktionen direkt in SQL nutzen. \n", "Um eine normale Single-Row-Funktion zu Verwenden muss man diese in der Verbindung mit `create_function` registieren.\n", "Dieser Mechanismus funktioniert auch mit Multi-Row-Funktionen. Eine Multi-Row-Funktion wird in Python durch eine Klasse abgebildet. " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#\n", "# Single Row Function\n", "#\n", "def format_ename(t):\n", " return \"Emp Name: \" + t \n", "\n", "\n", "conn.create_function(\"format_ename\", 1, format_ename)\n", "cur = conn.cursor()\n", "cur.execute(\"select format_ename(e.name) from emp e\")\n", "# Zum Testen der Funktion wird nur der Wert ausgegeben\n", "print(cur.fetchone()[0])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#\n", "# Das funktioniert auch mit Aggregatsfunktionen\n", "#\n", "class SqrSum:\n", " def __init__(self):\n", " self.count = 0\n", "\n", " def step(self, value):\n", " self.count += value*value\n", "\n", " def finalize(self):\n", " return self.count\n", "\n", "conn.create_aggregate(\"sqr_sum\", 1, SqrSum)\n", "cur = conn.cursor()\n", "cur.execute(\"select sqr_sum(sal) from emp\")\n", "print(\"Die quadartische Summe der Gehälter ist \" + str(cur.fetchone()[0]))" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "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.8.0" } }, "nbformat": 4, "nbformat_minor": 2 }