Python + MySQL

Uit De Vliegende Brigade
Ga naar: navigatie, zoeken

MySQL-driver

Om vanuit Python met MySQL te communiceren, heb je een driver nodig.

Inventaris

  • MySQLdb - Vermoedelijk meest gebruikt, maar schijnt complicaties te geven tijdens installatie ivm. externe afhankelijkheden [1]
  • mysqlclient - Opvolger van MySQLdb. Hierdoor is MySQLdb achterhaald geworden
  • MySQL Connector/Python - Veelbelovend, 100% Python (dus bv. geen C-bibliotheken), afkomstig van MySQL, maar slechte performance, licentie-issues en mogelijk significante bugs
  • PyMySQL
  • oursql
  • SQLAlchemy - Suite of tools, wo. een driver (geloof ik)
  • Storm

Keuze (okt. 2018)

Er is een interessante discussie over wat de beste driver is. Die discussie lijkt zich toe te spitsen op Mysqlclient vs. Connector/Python [2], [3] - Ik kies deze laatste.

Installatie Connector/Python (okt. 2018)

  • Downloaden naar buroblad
  • Dubbelklikken
  • Installeren
  • Klaar.

ORM

De standaard-manier om te interacteren met een MySQL-database vanuit Python, is door SQL-commando's in strings te stoppen, en deze te executeren. Een verschrikkelijke manier: Complex, foutgevoelig en vermoedelijk lastig te debuggen. De oplossing voor dit probleem heet ORM, oftewel object-relational mappings. Hierdoor kun je rechtstreeks Python-db-gerelateerde commando's gebruiken. Dat maakt het leven een stuk eenvoudiger. Nadeel: Je moet mogelijk een nieuwe syntaxis leren.

Inventaris

Keuze (okt. 2018)

  • SQLAlchemy - Lijkt de standaardoplossing te zijn.

Installatie SQLAlchemy (okt. 2018)

  • Download .tar.gz-bestand naar
  • Pak het bestand uit en plaats inhoud in een map onder /usr/local/bin/ In mijn geval is dat map /usr/local/bin/SQLAlchemy-1.2.12
  • python setup.py install - Alleen C-gedeelte lukt niet
  • Test: Ga naar een andere map (m'n projetmap in dit geval):
python
Python 2.7.12 (default, Dec  4 2017, 14:50:18) 
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sqlalchemy
>>> sqlalchemy.__version__
'1.2.12'

Programmeervoorbeelden

Mijn eerste db-connectie

Zonder ORM:

#! /usr/bin/python
#####################################################################################
#
import mysql.connector

cnx = mysql.connector.connect(
	user='xxx',
	password='yyy',
	host='127.0.0.1',
	database='zzz')

cursor = cnx.cursor()

cursor.execute("show databases;")
result=cursor.fetchall()
print result

cnx.close	

Uitvoer - In een nogal gaar format (zie hieronder!):

[(u'information_schema',), (u'zzz',), (u'mysql',), (u'performance_schema',)]

Tuple unpacking

Het gare format waarin data wordt weergegeven, is omdat ik samengestelde data (tuples?) als één object probeer weer te geven. De truuk is, om die data te splitsen [6]:

#! /usr/bin/python
#
# Brainspotting > New site (2018) > Import practitioners through XML-RPC > 
# Talk to MySQL-database & fetch data > Example http://www.mysqltutorial.org/python-mysql-query/
#
#####################################################################################
# Load libraries
#####################################################################################
#
import mysql.connector

# from mysql.connector import MySQLConnection, Error   # Werkt niet + niet nodig
# from python_mysql_dbconfig import read_db_config     # Werkt niet + niet nodig
 
 
def query_with_fetchall():
    try:

        cnx = mysql.connector.connect(
            user='xxx',
            password='yyy',
            host='127.0.0.1',
            database='zzz')


        cursor = cnx.cursor()
        cursor.execute("SELECT * FROM practitioner_tmp")
        rows = cursor.fetchall()
 
        # Object "rows" contains all row data, as a tuple
        #################################################
        #
        print('Total Row(s):', cursor.rowcount)
        i=0
        for row in rows:

            i=i+1
            
            # Untuple
            ################################################
            #
            # https://stackoverflow.com/questions/25121829/mysql-query-returns-data-uexample
            #
            print(i),
            print(row)[0],  # Eerste veld
            print(row)[1],  # Etc.
            print(row)[2],
            print(row)[3]

    except Error as e:
        print(e)
 
    finally:
        cursor.close()
        cnx.close()
 
 
if __name__ == '__main__':
    query_with_fetchall()

Bronnen

Drivers

ORM's

SQLAlchemy

Fetch data (Connector/Python API)