SQL¶
Abfrage von Autoren der Uni-Bibliografie der TUC
#!/usr/bin/env python3
# -*- coding: utf8 -*-
#
# Abfrage von Autoren der Uni-Bibliografie
#
# s.a.
# Python 3 and MySQL
# https://stackoverflow.com/questions/4960048/python-3-and-mysql
#
# pip install mysqlclient
#
# 22.1.2018
from __future__ import print_function
import MySQLdb, MySQLdb.cursors
# Daten für den Zugriff auf die Datenbank
db = 'unibiblio'
db_timeout = 5
db_user = 'opusread'
db_host = 'opac.bibliothek.tu-chemnitz.de'
db_pass = 'opusread'
# unser SELECT
stmt = '''
select
source_opus,
creator_name,
creator_kst
from
opus_autor
order by
source_opus,
reihenfolge
limit 10
'''
# Verbindung zur Bibliografie-Datenbank öffnen
dbh = MySQLdb.connect(host = db_host, user = db_user, passwd = db_pass,
db = db, connect_timeout = db_timeout)
# Abfrage ohne Cursor ausführen und das Resultat holen; use_result() belässt es
# auf dem Server, man holt es zeilenweise mit result.fetch_row() ab; mit
# store_result() holt man das Ergebnis geschlossen auf den Klienten
dbh.query(stmt)
result = dbh.use_result()
print('result', dir(result), '\n')
# Resultat-Zeilen sukzessive mit fetch_row() holen
print('ohne Cursor')
while True:
result_zeile = result.fetch_row()
print(repr(result_zeile))
if not result_zeile:
# keine Daten mehr da
break
# einen Cursor anlegen
cursor = dbh.cursor()
# falls man intern use_result() statt store_result() nutzen und so das Resultat
# auf dem MySQL-Server statt dem Klienten speichern will, muss man die
# Cursor-Klasse SSCursor verwenden:
#cursor = dbh.cursor(cursorclass = MySQLdb.cursors.SSCursor)
print('\ncursor', dir(cursor))
print('\ncursor.arraysize %d\n' % cursor.arraysize, end=' ')
# Abfrage nochmal ausführen
count = cursor.execute(stmt)
print('\ncount = %d' % count)
# über dem Cursor iterieren
print('iteriere über dem Cursor')
for row in cursor:
print(repr(row))
# nochmal mit fetch_one()
count = cursor.execute(stmt)
print('\ncount = %d' % count)
print('fetchone()')
while True:
row = cursor.fetchone()
print(repr(row))
if not row:
break
# und nochmal mit fetch_many()
count = cursor.execute(stmt)
print('\ncount = %d' % count)
print('fetchmany()')
while True:
rows = cursor.fetchmany()
print(repr(rows))
if not rows:
break
# und nochmal mit fetch_many(7)
count = cursor.execute(stmt)
print('\ncount = %d' % count)
print('fetchmany(7)')
while True:
rows = cursor.fetchmany(7)
print(len(rows), '==>', repr(rows))
if not rows:
break
# Verbindung zur Datenbank lösen
dbh.close()
Abfrage von Autoren der Uni-Bibliografie und Ausgabe in eine CSV-Datei
#!/usr/bin/env python3
# -*- coding: utf8 -*-
#
# Abfrage von Autoren der Uni-Bibliografie und Ausgabe in eine CSV-Datei
#
# anschließend wird die generierte CSV-Datei eingelesen und "schön" formatiert
# angezeigt
#
# s.a.
# Python 3 and MySQL
# https://stackoverflow.com/questions/4960048/python-3-and-mysql
#
# pip install mysqlclient
#
# 22.1.2018
from __future__ import print_function
import MySQLdb, csv
# Daten für den Zugriff auf die Datenbank
db = 'unibiblio'
db_timeout = 5
db_user = 'opusread'
db_host = 'opac.bibliothek.tu-chemnitz.de'
db_pass = 'opusread'
# die Liste der abzufragenden SQL-Felder
fields = (
'source_opus',
'creator_name',
'creator_kst',
)
# Select-Statement für die Abfrage; die Liste der Felder wird eingefügt
stmt = '''
select
%s
from
opus_autor
order by
source_opus,
reihenfolge
limit 10
''' % ','.join(fields)
# Verbindung zur Bibliografie-Datenbank öffnen
dbh = MySQLdb.connect(host = db_host, user = db_user, passwd = db_pass,
db = db, connect_timeout = db_timeout)
# einen DictCursor für unsere SQL-Abfragen erzeugen, der den Zugriff auf die
# Felder über die Feldnamen gestattet
cursor = dbh.cursor(MySQLdb.cursors.DictCursor)
# gemäß der Empfehlung unter
# http://www.php.net/manual/de/function.mysql-set-charset.php#86455
# die Verbindung konsequent auf UTF8 umstellen
cursor.execute("SET character_set_results = 'utf8', character_set_client = 'utf8',"
"character_set_connection = 'utf8',"
"character_set_database = 'utf8', character_set_server = 'utf8'")
# Abfrage starten
cursor.execute(stmt)
# Generatorfunktion, die schrittweise die CSV-Zeilen liefert
def data_gen(cursor):
# als 1. Zeile liefern wir das Tupel der Felder
csv_fields = 'source_opus', 'creator_kst', 'creator_name'
yield csv_fields
# nun der Reihe nach die abgefragten Sätze zurückgeben; wir liefern die Liste
# der Feldinhalte gemäß obiger Feldreihenfolge
for line in cursor:
yield [line[csv_field] for csv_field in csv_fields]
# Name der CSV-Datei
csv_filename = 'liste.csv'
# die Datenbank satzweise lesen und in die CSV-Datei ausgeben
with open(csv_filename, 'w') as csv_file:
# writerows gibt alle Elemente der angegebenen Sequenz (hier die von der
# Generatorfunktion erzeugten Zeilen/Sequenzen) in die CSV-Datei aus
csv.writer(csv_file).writerows(data_gen(cursor))
# nun die gerade generierte CSV-Datei einlesen und "schön" ausgeben
with open(csv_filename) as csv_file:
# zuerst Zeile 1 einlesen und in die Feldnamen aufspalten
#
# - csv_file.readline() liest die 1. Zeile aus der CSV-Datei
# - wir generieren einen CSV-Reader und übergeben ihm als zu lesende Sequenz
# eine einelementige Liste, die nur die 1. Zeile der CSV-Datei enthält
# - next() liefert das nächste Element eines Iterators und holt somit das
# Ergebnis des CSV-Readers ab
fieldnames = next(csv.reader([csv_file.readline()]))
# die maximale Länge der Feldnamen ermitteln
max_len = max(len(fn) for fn in fieldnames)
# daraus einen passenden Formatstring erstellen, in den max_len als Länge des
# String-Platzhalters %s einfließt
fmt = '%%%ds: %%s' % max_len
# einen DictReader für die restlichen Zeilen des CSV-Files generieren;
# durch das obige readline() liefert csv_file hier die Sequenz der CSV-Zeilen
# ab Zeile 2
reader = csv.DictReader(csv_file, fieldnames)
# die CSV-Zeilen durchlaufen
for line in reader:
# pro Zeile die Liste der Feldnamen durchgehen
#print repr(line)
for fn in fieldnames:
# jedes Feld formatiert ausgeben
if 1:
# Variante 1:
# der * bei %*s symbolisiert eine dynamische Länge für den
# String-Platzhalter %s, die wir durch das erste Argument max_len
# angeben
print('%*s: %s' % (max_len, fn, line[fn]))
else:
# Variante 2:
# Nutzung des oben erstellten Formatstrings
print(fmt % (fn, line[fn]))
print()