diff --git a/lectures/lecture5/lab/databaser.ipynb b/lectures/lecture5/lab/databaser.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..41c8d0dd36e4efb7cf3780c20015cf961230c719 --- /dev/null +++ b/lectures/lecture5/lab/databaser.ipynb @@ -0,0 +1,333 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### MySQL database\n", + "\n", + "Man kan koble opp mot forskjellige databaser i Python:\n", + "- GadFly\n", + "- mSQL\n", + "- **MySQL**\n", + "- PostgreSQL\n", + "- Microsoft SQL Server 2000\n", + "- Informix\n", + "- Interbase\n", + "- Oracle\n", + "- Sybase\n", + "- …\n", + "\n", + "Eller bruke SqlLite3 \n", + "- Egen database modul for Python\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "# Viser hvordan vi kobler oss mot MySQL og leser/oppdaterer data.\n", + "# Må installere PyMySQL først: pip install pymysql\n", + "import pymysql" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For å logge oss inn på databasen, må vi ha en konto på database-serveren.\n", + "\n", + "Følgende informasjon må vi ha:\n", + "\n", + "- host: navn på database-server\n", + "- user: brukernavn for å koble oss til serveren\n", + "- password: passord for å koble oss til serveren\n", + "- database: database seed (en database server kan inneholde mange database instanser)\n", + "\n", + "Dersom vi ikke ønsker å \"hardkode\" passord (skrive det i programmet i klar tekst eller i en fil), kan vi bruke modulen **getPass** for å taste inn passordet når programmet starter.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "# importer funksjonen getpass fra modulen getpass.\n", + "# Vi bruker getpass for å lese passord fra bruker (slik at det ikke vises i klartekst)\n", + "from getpass import getpass" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "# Database connection object\n", + "global db_connection\n", + "db_connection = None\n", + "\n", + "my_host = \"mysql.stud.iie.ntnu.no\"\n", + "my_user = \"rouhani\" # Skriv inn brukernavnet ditt her\n", + "my_password = getpass()\n", + "my_database = \"rouhani\"\n", + "\n", + "def get_db_connection():\n", + " if 'db_connection' in globals():\n", + " db_connection = pymysql.connect(host = my_host, user = my_user, password = my_password, database = my_database)\n", + " return db_connection" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Koble opp mot databasen og les fra en tabell" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "('TBM.0832', 'Stol', 1, '12.04.2023', 'Hanne', '12.04.2023', 'Kristin', 'Olsen Giver', 'PL.A1.B2', 'Tester')\n", + "('TBM.4892', 'Kommode', 1, '03.04.2011', 'Museumsbestyrer Olav N', '29.04.2012', 'Museumsbestyrer Olav Nilsen', 'Museumsbestyrer Olav Nilsen', 'M1.R2.P1.H1', '')\n" + ] + } + ], + "source": [ + "\n", + "\n", + "with get_db_connection() as my_db:\n", + " my_cursor = my_db.cursor()\n", + "\n", + " my_sql = \"SELECT * FROM objects\"\n", + " my_cursor.execute(my_sql)\n", + "\n", + " for row in my_cursor:\n", + " print(row)\n", + "\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Koble opp mot databasen og oppdater rader i en tabell\n" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "#Sjekk om regnr existerer i databasen\n", + "def reg_no_exist(reg_no,table_name):\n", + " \"\"\"\n", + " Sjekk om regnnr existerer allerede i basen\n", + " :param regnr: type string\n", + " :return: boolean\n", + " \"\"\"\n", + " with get_db_connection() as db:\n", + "\n", + " cursor = db.cursor()\n", + " sql = \"SELECT count(reg_no) as reg_no_count FROM {0} WHERE reg_no='{1}'\".format(table_name,reg_no)\n", + " cursor.execute(sql)\n", + "\n", + " reg_no_count = 0\n", + "\n", + " for row in cursor:\n", + " reg_no_count= row[0]\n", + "\n", + " if reg_no_count==0:\n", + " return False\n", + " else:\n", + " return True\n", + "\n", + "#Lagrer gjenstand i basen\n", + "def save_object_db(giver_val,\n", + " innlemmet_dato_val,\n", + " kategori_id,\n", + " kommentar_val,\n", + " mottatt_av_val,\n", + " navn_val,\n", + " plassering_val,\n", + " registrert_av_val,\n", + " registrerings_dato_val,\n", + " reg_no):\n", + " \"\"\"\n", + " Lagre gjenstand info i databasen.\n", + " Dersom den finnes allerede, blir gjenstand oppdatert\n", + " Dersom den ikke finnes, blir den opprettet.\n", + " :param giver_val: string\n", + " :param innlemmet_dato_val: string\n", + " :param kategori_id: int\n", + " :param kommentar_val: string\n", + " :param mottatt_av_val: string\n", + " :param navn_val: string\n", + " :param plassering_val: string\n", + " :param registrert_av_val: string\n", + " :param registrerings_dato_val: string\n", + " :param regnr: string\n", + " :return:\n", + " \"\"\"\n", + "\n", + " #****************************************\n", + " # Oppgave 4.1\n", + " # Fullfør innholdet i denne funksjonen!\n", + " #****************************************\n", + "\n", + " with get_db_connection() as my_db:\n", + "\n", + " my_db.autocommit(True)\n", + " cursor = my_db.cursor()\n", + "\n", + " if reg_no_exist(reg_no,'objects'):\n", + " cursor.execute(\"UPDATE objects SET giver=%s,in_date=%s,category_id=%s,comment=%s,received_by=%s,name=%s,placement=%s,reg_by=%s,reg_date=%s WHERE reg_no=%s\",\n", + " (giver_val,innlemmet_dato_val,kategori_id,kommentar_val,mottatt_av_val,navn_val,plassering_val,registrert_av_val,registrerings_dato_val,reg_no))\n", + " else:\n", + " cursor.execute(\"INSERT INTO objects (giver,in_date,category_id,comment,received_by,name,placement,reg_by,reg_date,reg_no) VALUES(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)\",\n", + " (giver_val,innlemmet_dato_val,kategori_id,kommentar_val,mottatt_av_val,navn_val,plassering_val,registrert_av_val,registrerings_dato_val,reg_no))\n", + "\n", + "#Oppdater eksisterende rad\n", + "save_object_db('Olsen Giver','12.04.2023', 1, 'Tester', 'Kristin', 'Stol', 'PL.A1.B2','Hanne','12.04.2023','TBM.0832')\n", + "\n", + "\n", + "#legg til ny rad\n", + "save_object_db('Olsen Giver','12.04.2023', 1, 'Tester', 'Kristin', 'Stol', 'PL.A1.B2','Hanne','12.04.2023','TBM.0832-N')\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Koble opp mot databasen og fjern rader fra en tabell" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "#Slett gjenstand\n", + "def delete_object(reg_no):\n", + " \"\"\"\n", + " :param regnr: Registreriongsnr på gjenstand som skal slettes\n", + " :return: ingen returverdi.\n", + "\n", + " Funksjonen skal finne gjenstanden og slette denne.\n", + " 1. Slett fra properties-tabellen for det gitte registreringsnummeret\n", + " 2. Slett fra provenances-tabellen for det gitte registreringsnummeret\n", + " 3. Slett fra objects-tabellen for det gitte registreringsnummeret\n", + "\n", + " Dersom sletting går bra, skriv en melding til skjermen.\n", + " \"\"\"\n", + "\n", + " #******************************************\n", + " # Oppgave 4.3\n", + " # Fullfør denne funksjonen\n", + " #******************************************\n", + "\n", + "\n", + " with get_db_connection() as db:\n", + " db.autocommit(True)\n", + "\n", + " cursor = db.cursor()\n", + " cursor.execute(\"DELETE from properties where reg_no='\" + reg_no+\"'\")\n", + " cursor.execute(\"DELETE from provenances where reg_no='\" + reg_no+\"'\")\n", + " cursor.execute(\"DELETE from objects where reg_no='\" + reg_no+\"'\")\n", + "\n", + "\n", + "delete_object('TBM.0832-N')" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### a) Lag en funksjon som legger til nye kategorier i databasen" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Skriv kode her" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### b) Lag en funksjon som søker etter et object basert på reg_no" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Skriv kode her" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### c) Frivillig: Endre funksjonen i oppgave b slik at det søkes på enten reg_no eller navn (deler eller hele reg_no/navn)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Skriv kode her" + ] + } + ], + "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.11.2" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +}