S3 - Python - MongoDB - MySQL - Flask
S3 - Python - MongoDB - MySQL - Flask
1. Python – MySQL
Pentru conexiunea cu o bază de date MySQL se parcurg următorii pași:
1. Se importă pachetul mysql.connector în Python:
import mysql.connector
2. Se precizează conexiunea la serverul MySQL:
db_connection=mysql.connector.connect(
host="localhost",
user ="bdsa",
passwd="Bdsa_1234",
database="clienti_daune",port=3306,auth_plugin='mysql_native_passwor
d')
3. Se deschide un cursor:
cursor=db_connection.cursor()
4. Se specifică într-o variabilă de tip șir de caractere comanda SQL, inclusiv parametrii
precizați prin %s. Se execută interogarea prin intermediul cursorului:
sql_stm="""select * from clienti_daune.T_CLIENTI_LEASING where
SUMA_SOLICITATA > %s """
params=(v_suma,)
cursor=db_connection.cursor()
cursor.execute(sql_stm,params)
lista_mysql=cursor.fetchall()
pprint(lista_mysql)
1
connection = cx_Oracle.connect("student_ps", "oracle",
"37.120.250.20/oracle")
sql_oracle="""SELECT ID_CLIENT, NUME_CLIENT, PROFESIA, SEX, MONEDA,
VENIT_ANUAL, CONT_CURENT, VENIT_ANUAL_RON, VAL_CREDITE_RON, VARSTA,
CATEGORIE
, DESCRIERE, PRESCORING, SUMA_DEPOZIT, FIDELITATE, STARE_CIVILA,
PROBABILITATE_CONTRACTARE_N, SUMA_SOLICITATA, PRAG_SUMA_ACORDATA,
data
FROM t_clienti_leasing where suma_solicitata > :p_suma """
cursor = connection.cursor()
v_suma = input("Introduceti suma ceruta pentru creditare: ");
cursor.execute(sql_oracle, p_suma=v_suma)
lista_clienti=cursor.fetchall()
#inchidere cursor si conexiune cu Oracle
cursor.close()
connection.close()
#afisare lista clienti
#pprint (lista_clienti)
database="clienti_daune",port=3306,auth_plugin='mysql_native_passwor
d')
2
#print(str(cursor.rowcount) + " au fost inserate in tabela
T_CLIENTI_LEASING")
cursor.close()
db_connection.commit()
db_connection.close()
database="clienti_daune",port=3306,auth_plugin='mysql_native_passwor
d')
#db_connection.autocommit = False
#stergem inregistrarile pre-existente daca este cazul
cursor=db_connection.cursor()
del_stm = """UPDATE clienti_daune.T_CLIENTI_LEASING SET
PROBABILITATE_CONTRACTARE_N =0 WHERE PRESCORING BETWEEN %s and %s"""
params=(p_min, p_max,)
cursor.execute(del_stm,params)
cursor.close()
#db_connection.commit()
3
db_connection.close()
Încărcarea datelor returnate de MySQL într-un DataFrame Pandas se realizează similar cu cea
utilizată de pachetul cx_Oracle. În acest caz utilizarea cursorului nu mai este necesară:
df = pd.read_sql(statement, con=db_connection,params={p1, p1, ….})
Exemplul 3: Să se returneze într-un DataFrame Pandas clientii cu vârsta mai mare decât o
valoare introdusă de la tastatură. Să se calculeze în funcție de profesia suma totală și valoarea
medie a sumelor solicitate de acești clienți. Să se reprezinte grafic.
from pprint import pprint
import mysql.connector
import pandas as pd
import matplotlib.pyplot as plt
#conexiunea cu baza de date MySQL
v_min = input("Introduceti limita inferioara pentru varsta: ")
db_connection=mysql.connector.connect(
host="localhost",
user ="bdsa",
passwd="Bdsa_1234",
database="clienti_daune",port=3306,auth_plugin='mysql_native_passwor
d')
Exemplul 4: Încărcați într-un DataFrame Pandas lista clienților care au o anumită profesie
întrodusă de la tastatură. Calculați valoarea medie a valorilor numerice grupate în funcție de
sex si moneda.
import mysql.connector
import pandas as pd
#conexiunea cu baza de date MySQL
v_profesia = input("Introduceti profesia: ")
v_profesia='%'+v_profesia.lower()+'%'
db_connection=mysql.connector.connect(
host="localhost",
user ="bdsa",
passwd="Bdsa_1234",
4
database="clienti_daune",port=3306,auth_plugin='mysql_native_passwor
d')
Exemplul 5: Transformați exemplul de mai sus astfel încât codul să ruleze sub formă de Web
API și să fie accesibil printr-un URL. Vom utiliza Flask pentru a putea rula codul sub forma
unui Web API. Modalitatea de lucru cu Flask a fost descrisă în curs.
import mysql.connector
import pandas as pd
import flask
from flask import request, jsonify
import json
app = flask.Flask(__name__)
app.config["DEBUG"] = False
# home page
@app.route('/', methods=['GET'])
def home():
return '''<h1>Regasirea clientilor cu o anumita profesie</h1>
<p>API pentru calcularea statisticilor in functie de
profesie.</p>'''
@app.errorhandler(404)
def page_not_found(e):
return "<h1>404</h1><p>The resource could not be found.</p>",
404
# pagina: http://127.0.0.1:5000/api/v1/resources/profesie_clienti?
profesia=inginer
@app.route('/api/v1/resources/profesie_clienti', methods=['GET'])
def api_profesie_clienti():
# Verificarea parametrului introdus in URL.
if 'profesia' in request.args:
v_profesia = str(request.args.get('profesia', type=str))
v_profesia = '%' + v_profesia.lower() + '%'
else:
return "Error: Nu a fost precizat profesia. Va rugam
specificati o profesie: Inginer, Medic, Avocat....."
5
db_connection = mysql.connector.connect(
host="localhost",
user="bdsa",
passwd="Bdsa_1234",
database="clienti_daune", port=3306,
auth_plugin='mysql_native_password')
app.run()
6
2. Python - MongoDB
Interacțiunea dintre Python și MongoDB este posibilă prin intermediul pachetului pymongo
care conține metode pentru accesul la bazele de date și colecțiile stocate în MongoDb.
Pașii pentru accesul la documentele din MongoDB sunt următorii:
9. Datele din cursor se pot încărca direct într-o listă de documente MongoDB sub forma de
dicționare:
set_clienti=list(cursor)
O altă variantă: se poate inițializa o listă goală și la fiecare iterație a cursorului se adaugă un
document în listă. Avantajul ar fi că se pot face prelucrări suplimentare pe fiecare record din
cursor înaintea încărcării în listă, de exemplu nu încărcăm documentele pentru care valoarea
daunei este null:
set_clienti=[]
for r in cursor:
if str(r['VALOARE_DAUNA'])!='nan':
set_clienti.append(r)
7
print (set_clienti)
O variantă mai elegantă de afișare o oferă pachetul pprint și metoda pprint. Vom adăuga la
început importul acesteia:
from pprint import pprint
Exemplul 7. Modificăm exemplul de mai sus astfel încât să fie încărcate toare
documentele, deci lista va fi încărcată cu set_clienti=list(cursor).
Calculăm valoarea totală a daunelor pentru o marcă auto introdusă de utilizator de la
tastatură (cu metoda input)
import pymongo
from pprint import pprint
conn = pymongo.MongoClient("mongodb://37.120.249.57:27017/")
db = conn["daune_leasing"]
collection = db["clienti_daune"]
8
projection={"_id":0,
"TARAPRODUCATOR":1,
"REGIUNEPRODUCATOR":1,
"MARCA":1,
"MODEL":1,
"VALOARE_DAUNA":1
}
sort=[("MARCA", 1)]
cursor=collection.find({},projection=projection, sort=sort)
set_clienti=list(cursor)
#pprint (set_clienti)
cursor.close()
#prelucrarea datelor din lista
v_marca = input("Introduceti marca: ")
print ("Marca selectata este : ", v_marca)
total_daune=0
for r in set_clienti:
if str(r['MARCA']).find(v_marca.upper())!=-1:
total_daune=total_daune+r['VALOARE_DAUNA']
print ("Valoarea totala a daunelor pentru marca", v_marca, " este: ",
total_daune)
9
Exemplul 9. Să se modifice exemplul de mai sus astfel încât să se afișeze cuvintele cele
mai frecvente pentru o anumită marca auto:
import pymongo
from pprint import pprint
conn = pymongo.MongoClient("mongodb://37.120.249.57:27017/")
db = conn["daune_leasing"]
collection = db["clienti_daune"]
projection = {"_id": 0,
"DAUNA": 1,
"MARCA": 1,
"MODEL": 1,
"VALOARE_DAUNA": 1
}
sort = [("DAUNA", -1)]
cursor = collection.find({}, projection=projection, sort=sort)
set_clienti = list(cursor)
cursor.close()
v_marca = input("Introduceti marca: ")
lista_cuvinte=[]
try:
for dauna in set_clienti:
if str(dauna['MARCA']).find(v_marca.upper()) != -1:
lista_cuvinte=lista_cuvinte +
str(str(dauna['DAUNA']).lower()).split()
except:
print('Nu s-a precizat dauna!')
#print(lista_cuvinte)
# numaram cuvintele si le adaugam intr-un dictionar
#initial dictionarul este gol si va fi completat cu cuvinte
dictionar = {}
for cuvant in lista_cuvinte:
if cuvant not in dictionar:
dictionar[cuvant] = 1
else:
dictionar[cuvant] += 1
#formam lista cuvintelor si a frecventei de aparitie sortata descrescator
aparitie = []
for key, value in dictionar.items():
if key not in ('the', 'and', 'to', 'a', 'in', 'not', 'of') and value>50:
aparitie.append((value, key))
aparitie.sort(reverse=True)
pprint(aparitie)
Pentru analiza mai avansată a datelor din MongoDB se poate utiliza pachetul pandas.
Conexiunea cu MongoDB se gestionează de către pachetul PyMongo, iar datele din cursor se
încarcă într-un DataFrame Pandas astfel:
df = pd.DataFrame.from_dict(list(cursor))
Exemplul 10. Majorați cu 10% pretul manoperei pentru autoturismele fabricate inainte de
2010 și care au componenta BATTERY defectă.
import pymongo
import pandas as pd
from pprint import pprint
conn = pymongo.MongoClient("mongodb://37.120.249.57:27017/")
db = conn["daune_leasing"]
collection = db["clienti_daune"]
projection = {"_id": 0,
"AN_FABRICATIE": 1,
10
"MARCA": 1,
"COMPONENTA": 1,
"PRET_MANOPERA": 1
}
sort = [("MARCA", 1)]
cursor = collection.find({}, projection=projection, sort=sort)
#incarcam in dataframe inregistrarile din cursor
df = pd.DataFrame.from_dict(list(cursor))
cursor.close()
pprint (df.loc[(df['AN_FABRICATIE'] < 2010) & (df['COMPONENTA']
=='BATTERY'), 'PRET_MANOPERA'])
df.loc[(df['AN_FABRICATIE'] < 2010) & (df['COMPONENTA'] =='BATTERY'),
'PRET_MANOPERA']=df.loc[(df['AN_FABRICATIE'] < 2010) & (df['COMPONENTA']
=='BATTERY'), 'PRET_MANOPERA']*1.10
pprint(df.loc[(df['AN_FABRICATIE'] < 2010) & (df['COMPONENTA']
=='BATTERY'), 'PRET_MANOPERA'])
df.to_csv('clienti_daune_mod.csv')
Exemplul 11: Modificați exemplul de mai sus astfel încât condiția de regăsire a datelor să
fie inclusă în clauza find({}) utilizată la încărcarea datelor din MongoDB.
În acest caz, setul de date încărcat în DataFrame-ul din pandas este redus și nu mai este
necesară localizarea datelor cu df.loc.
Fișierul excel salvat va conține doar autoturismele selectate.
import pymongo
import pandas as pd
from pprint import pprint
conn = pymongo.MongoClient("mongodb://37.120.249.57:27017/")
db = conn["daune_leasing"]
collection = db["clienti_daune"]
projection = {"_id": 0,
"AN_FABRICATIE": 1,
"MARCA": 1,
"COMPONENTA": 1,
"PRET_MANOPERA": 1
}
sort = [("MARCA", 1)]
cursor = collection.find({"COMPONENTA": "BATTERY",
"AN_FABRICATIE": {'$lt': 2010}}, projection=projection,
sort=sort)
df = pd.DataFrame.from_dict(list(cursor))
cursor.close()
pprint (df)
df['PRET_MANOPERA']=df['PRET_MANOPERA']*1.10
pprint(df)
df.to_csv('clienti_daune_mod.csv')
Exemplul 12. Folosind agregările din MongoDB încărcați într-un DataFrame marca
autoturismelor, valoarea totală a daunelor și pretul manoperei pe fiecare marcă.
Introduceți o nouă coloană în df denumită PROCENT_MANOPERA în care să calculați
ponderea manoperei din valoarea totală a daunelor pe fiecare marcă. Ordonați setul de date
în ordinea descrescătoare a acestui procent și salvați datele într-un fișier .csv
import pymongo
import pandas as pd
from pprint import pprint
conn = pymongo.MongoClient("mongodb://37.120.249.57:27017/")
db = conn["daune_leasing"]
11
collection = db["clienti_daune"]
pipeline=[{'$group' : {
"_id" : "$MARCA",
"VALOARE_MANOPERA": { '$sum': "$PRET_MANOPERA" },
"VALOARE_DAUNA": { '$sum': "$VALOARE_DAUNA" }
}},
{ '$sort': {"_id": 1}}]
cursor = collection.aggregate(pipeline)
df = pd.DataFrame.from_dict(list(cursor))
cursor.close()
df['PROCENT_MANOPERA'] =df['VALOARE_MANOPERA'] / df['VALOARE_DAUNA']*100
pprint (df)
12
Integrarea dintre MySQL și MongoDB.
Exemplul 14: Într-un df încărcați din tabela T_CLIENTI_LEASING din MySQL toți clientii
care au solicitat pentru creditare o suma mai mare decât o valoare introdusă de la tastatură.
În alt df încărcați din MongoDB daunele cu valoarea mai mare de 1000.
Realizați o joncțiune între cele două df pe coloana comună ID_CLIENT.
import pandas as pd
from pprint import pprint
#regasirea datelor din MySQL
import mysql.connector
#conexiunea cu baza de date MySQL
v_min = input("Introduceti limita pentru suma solicitata: ")
db_connection=mysql.connector.connect(
host="localhost",
user ="bdsa",
passwd="Bdsa_1234",
database="clienti_daune",port=3306,auth_plugin='mysql_native_passwor
d')
13
"MARCA": 1,
"COMPONENTA": 1,
"PRET_MANOPERA": 1,
"VALOARE_DAUNA":1,
"ID_CLIENT":1
}
sort = [("ID_CLIENT", 1)]
cursor = collection.find({"VALOARE_DAUNA": {'$gt': 1000}},
projection=projection, sort=sort)
df_m = pd.DataFrame.from_dict(list(cursor))
cursor.close()
df_m['PRET_COMPONENTE']=df_m['VALOARE_DAUNA']-df_m['PRET_MANOPERA']
df = pd.merge(df_sql,df_m, left_on=df_sql['ID_CLIENT'].astype(int),
right_on=df_m['ID_CLIENT'])
pprint(df)
Exemplul 15:Transformați exemplul de mai sus într-un API Web. Introduceți suplimentar un
parametru pentru selectarea valorii minime a daunelor.
import pandas as pd
import flask
from flask import request, jsonify
import json
app = flask.Flask(__name__)
app.config["DEBUG"] = False
# home page
@app.route('/', methods=['GET'])
def home():
return '''<h1>Regasirea clientilor cu daune</h1>
<p>API pentru afisarea clientilor cu daune.</p>'''
@app.errorhandler(404)
def page_not_found(e):
return "<h1>404</h1><p>The resource could not be
foundTralala.</p>", 404
# pagina: http://127.0.0.1:5000/api/v1/resources/daune_clienti?
suma_solicitata=7000&valoare_dauna=1000
@app.route('/api/v1/resources/daune_clienti', methods=['GET'])
def api_daune_clienti():
# Verificarea parametrului introdus in URL.
if 'suma_solicitata' in request.args:
v_min = int(request.args['suma_solicitata'])
else:
return "Error: Nu a fost precizat suma minima ceruta pentru
14
creditate."
if 'valoare_dauna' in request.args:
v_dauna = int(request.args['valoare_dauna'])
else:
return "Error: Nu a fost precizat valoare minima a daunei."
# regasirea datelor din MySQL
import mysql.connector
# conexiunea cu baza de date MySQL
db_connection = mysql.connector.connect(
host="localhost",
user="bdsa",
passwd="Bdsa_1234",
database="clienti_daune", port=3306,
auth_plugin='mysql_native_password')
df_m = pd.DataFrame.from_dict(list(cursor))
cursor.close()
df_m['PRET_COMPONENTE'] = df_m['VALOARE_DAUNA'] -
df_m['PRET_MANOPERA']
df = pd.merge(df_sql, df_m,
left_on=df_sql['ID_CLIENT'].astype(int), right_on=df_m['ID_CLIENT'])
ljson = df.to_json(orient='records')
return jsonify(json.loads(ljson))
app.run()
15
Teme propuse:
16
Pași pentru configurarea utilizatorului bdsa și a tabelei T_CLIENTI_LEASING utilizată
în seminar
Descărcați și instalați MySQL Community Server: https://dev.mysql.com/downloads/mysql/ .
Versiunea curentă este 8.0.19
user: bdsa
Password: Bdsa_1234
17
Click Apply.
2. Pentru utilizatorul nou creat, adaugam o noua schema BD pentru a putea crea in aceasta
tabelele de lucru. Click pe simbolul Create a New Schema….. sau click dreapta in zona
corespunzatoare schemelor. In fereastra aparuta completam numele schemei clienti_daune.
Click Apply.
3. Pentru utilizatorul bdsa acordam drepturi de acces pentru schema nou creata:
18
Din menul Server→User Proviledges→tab-ul Schema Priviledges, selectam utilizatorul bdsa
si butonul Add Entry. Din fereastra aparuta selectam schema clienti_daune:
Click OK. Din fereastra aparuta. acordam toate drepturile asupra acestei scheme si apoi click
Apply:
19
SEX VARCHAR(3), MONEDA VARCHAR(5), VENIT_ANUAL NUMERIC(12,2), CONT_CURENT NUMERIC(12,2), VENIT_ANUAL_RON
NUMERIC(12,2),
VAL_CREDITE_RON NUMERIC(12,2), DATA DATE, VARSTA NUMERIC, CATEGORIE VARCHAR(100), DESCRIERE VARCHAR(255),
PRESCORING NUMERIC,
SUMA_DEPOZIT NUMERIC, FIDELITATE NUMERIC, STARE_CIVILA VARCHAR(1), PROBABILITATE_CONTRACTARE_N NUMERIC
, SUMA_SOLICITATA NUMERIC, PRAG_SUMA_ACORDATA NUMERIC);
20