Aplikacja webowa w Pythonie – Flask – Łączenie z bazą danych – #5
Mamy już strukturę, layout’y, css-y i routing – nadszedł więc czas na coś, bez czego żadna poważna aplikacja nie może się obyć, czyli oczywiście bazę danych.
Czego potrzebuję?
Tak jak wspominałam już w pierwszym odcinku tutorialu – baza MySQL będzie teraz niezbędna. Jeżeli nie planujesz póki co wychodzić ze swoją aplikacją w szeroki świat i tworzysz ją na Windowsie, możesz zainstalować np. XAMPP-a i skorzystać z lokalnej bazy, którą oferuje. Dostaniesz wtedy również “w pakiecie” panel phpmyadmin, dzięki czemu nie będziesz musiał grzebać w skryptach i szybko utworzysz potrzebne archiwum. Jeśli pracujesz na Linuxie, masz ułatwione zadanie, bo wystarczy, że zainstalujesz odpowiednią paczkę. Wychodząc ze swoją aplikacją “na zewnątrz”, będziesz musiał natomiast umieścić ją na jakimś serwerze – weź wówczas pod uwagę, aby dysponował on usługą bazy danych.
W tutorialu przedstawię sposób połączenia się zarówno z naszym własnym, lokalnym MySQL-em, jak i zewnętrznym. Let’s go!
Instalacja Flask-MySQL
To tak naprawdę jedna linijka kodu. W folderze głównym (tym, w którym znajduje się plik run.py) wpisz komendę:
1 |
pip install flask-mysql |
Jeżeli korzystasz z Pythona 3.4 lub 3.5 komenda powinna zadziałać i doinstalować odpowiedni moduł. Jeśli nie, rozważ aktualizację.
Podłączenie bazy danych do Flaska
Od początku staramy się tworzyć naszą aplikację modułowo i teraz też będziemy kontynuować to podejście. W pliku inicjalizującym napiszemy odwołanie do bazy, a konkretne dane będziemy pobierać dopiero w skryptach routingu.
Zakładając, że Flask-MySQLdb jest zainstalowany i udało nam się utworzyć bazę danych na localhoście, nasz plik __init__.py powinien prezentować się następująco:
1 2 3 4 5 6 7 8 9 10 11 |
from flask import Flask from flaskext.mysql import MySQL app = Flask(__name__) mysql = MySQL() app.config['MYSQL_DATABASE_USER'] = 'root' app.config['MYSQL_DATABASE_PASSWORD'] = '' app.config['MYSQL_DATABASE_DB'] = 'flask' app.config['MYSQL_DATABASE_HOST'] = 'localhost' mysql.init_app(app) from hello_world import views |
Druga linijka importuje nam z doinstalowanego modułu klasę MySQL. Tworzymy jej obiekt, mysql = MySQL(), który następnie inicjalizujemy i łączymy z samą aplikacją ( mysql.init_app(app)). W międzyczasie konfigurujemy aplikację pod kątem samego połączenia. Mamy tutaj kilka zmiennych do zdefiniowania:
- ['MYSQL_DATABASE_USER']- nazwa użytkownika (w przypadku localhosta zazwyczaj root; w przypadku zewnętrznego serwera Twój login)
- ['MYSQL_DATABASE_HOST']- nazwa hosta (lokalnie – localhost; zewnętrzny serwer – zwykle adres z przeglądarki, pod którym się logujesz)
- ['MYSQL_DATABASE_PASSWORD']- hasło dla użytkownika (jeżeli localhost – zazwyczaj puste bądź ‘root’)
- ['MYSQL_DATABASE_DB']- nazwa bazy danych – ja nazwałam swoją ‘flask’
- ['MYSQL_DATABASE_PORT']- domyślnie 3306, prawdopodobnie nie będziesz musiał go edytować
Jest również kilka innych parametrów – jeśli chcesz o nich poczytać, odsyłam Cię na stronę tego rozszerzenia.
Kolejnym krokiem będzie utworzenie samej bazy i tabeli. Ja nazwałam tabelę ‘posty’ i stworzyłam dla niej cztery kolumny:
1 2 3 4 5 6 |
CREATE TABLE `posty` ( `ID` int(11) NOT NULL, `Nazwa` text NOT NULL, `Tresc` text NOT NULL, `Autor` text NOT NULL ); |
Następnie, dodałam do niej przykładowe dane (zrobienie tego zostawiam już Tobie ;)).
Przejdźmy teraz do views.py i dodajmy niezbędny import:
1 |
from hello_world import mysql |
Obiekt mysql, który utworzyliśmy w pliku inicjalizującym będzie mógł teraz zostać użyty właśnie przy routingu. Jako że stworzyliśmy tabelę o nazwie ‘posty’, będziemy chcieli wyświetlić właśnie to.
Podstronę posty już mamy, dlatego nową nazwiemy wszystkie-posty.
1 2 3 4 5 6 |
@app.route("/wszystkie-posty") def database_posts(): cursor = mysql.connect().cursor() cursor.execute("SELECT * from posty") data = cursor.fetchall() return render_template('database_posts.html', data = data) |
Łatwo zauważyć, że struktura routingu i render_template wyglądają identycznie jak dla pozostałych podstron – jedyną różnicą jest sposób pobrania danych data. Aby to zrobić, będzie nam potrzebny tak zwany cursor. To dzięki niemu połączymy się bazą i wywołamy nasze zapytanie (w tym przypadku SELECT * from posty). Następnie pod zmienną data podstawimy to, co zostało pobrane z bazy i przekażemy dalej do templatki.
Aby nasz kod mógł zadziałać potrzebujemy jeszcze pliku database_posts.html:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
{% extends "base.html" %} {% block title %}Posty{% endblock %} {% block content %} <h2>Posty</h2> <p> Witaj na podstronie, na której wyświetlone są posty z bazy danych. {% for row in data %} <article> <h3>{{ row[0] }}. {{ row[1] }}</h3> <p>{{ row[2] }}</p> <p><i>Autor: {{ row[3] }}</i></p> </article> {% endfor %} </p> {% endblock %} |
oraz podłączenia go do nawigacji:
1 |
<li><a href="{{url_for('database_posts')}}">Posty z bazy danych</a></li> |
I wszystko śmiga jak należy :)