Datenstruktur der Rückgabe einer Funktion ändern

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
Stephan_2021
User
Beiträge: 52
Registriert: Sonntag 11. Juli 2021, 09:43

Hallo,

ich habe folgende Funktion:

Code: Alles auswählen

from mysql.connector import connect

def get_data_for_grid(host, port, user, password, database, sql):
    with connect(
        host=host, port=port, user=user, password=password, database=database
    ) as connection:
        with connection.cursor() as cursor:
            cursor.execute(sql)
            return [
                tuple((str(item) if item is not None else "") for item in row)
                for row in cursor.fetchall()
            ]
Die Rückgabe dieser Funktion ist (quasi) ein Array mit Unterarrays, also beispielsweise so:

ArrayA(Arryx(12,...),Arrayy(28,...),Arrayz(17,...))

Wenn der Parameter sql so beschaffen ist das nur eine Spalte der Datentabelle abgefragt wird (z.B. "SELECT `MeineSpalte` from `MeineTabelle`") enthalten die Unterarrays jeweils nur einen Wert, z.B. also:

ArrayA(Arryx(12),Arrayy(28),Arrayz(17))

Wie muss die Funktion abgeändert werden, damit Sie, in einem solchen Fall, ein Ergebnis der Struktur:

ArrayA(12,28,17)

zurückgibt?


Weitere Informationen:
die obige Funktion wird mittels Starbasic in LibreOffice aufgerufen wie folgt:

Code: Alles auswählen

oMasterScriptProviderFactory = createUnoService("com.sun.star.script.provider.MasterScriptProviderFactory")
g_MasterScriptProvider = oMasterScriptProviderFactory.createScriptProvider("")
oScript = g_MasterScriptProvider.getScript("vnd.sun.star.script:mysqlgetdata2.py$get_data_for_grid?language=Python&location=user")
RS_Python = oScript.invoke(Array(DBHost,DBPort,DBUser,DBPass, NameDBInMySQL,"SELECT `MeineSpalte` from `MeineTabelle` ORDER BY `MeineSpalte` ASC"),Array(),Array())
Anschliesend muss ich derzeitig, per Starbasic noch RS_Python umformen, damit es für meine Zwecke die richtige Struktur hat:

Code: Alles auswählen

Dim tmparr(UBOUND(RS_Python))
For i = 0 To UBOUND(RS_Python)
	tmparr(i) = RS_Python(i)(0)
Next i
Und die Notwendigkeit dieser Umformung würde ich gerne dadurch vermeiden, das ich die Python-Funktion abändere.



Gruß
Stephan
Sirius3
User
Beiträge: 17710
Registriert: Sonntag 21. Oktober 2012, 17:20

Was sind denn `ArrayA`, `Arryx` und `Arrayy` für Objekte? Die sind nirgends definiert.
In Python hast Du Listen und Tuple, die dann wohl von Starbasic in Array umgewandelt werden. Beim Programmieren muß man sehr exakt arbeiten, weil ein Computer versteht gar nichts mehr, wenn man nur leicht abweicht.

Wenn Du keine Tuple willst, darfst Du keine Tuple erzeugen, sondern darfst nur row[0] in die Liste packen:

Code: Alles auswählen

def get_single_data_for_grid(host, port, user, password, database, sql):
    with connect(
        host=host, port=port, user=user, password=password, database=database
    ) as connection:
        with connection.cursor() as cursor:
            cursor.execute(sql)
            return [
                str(row[0]) if row[0] is not None else ""
                for row in cursor
            ]
Stephan_2021
User
Beiträge: 52
Registriert: Sonntag 11. Juli 2021, 09:43

Was sind denn `ArrayA`, `Arryx` und `Arrayy` für Objekte? Die sind nirgends definiert.
Naja, ich schrieb "beispielsweise" und also sollten das Beispiele sein. Den Ausdruck "Arrayy(17,...)" wollte ich so verstanden wissen das da ein konkretes Array ist (das ich "Arrayy" nannte aber vielleicht besser "Array_y" genannt hätte) und das mindestens einen Wert (nämlich 17) enthält und eventuell auch weitere Werte.

Mein Python-Buch sagt mir zwar das ein Array ungefähr dem entspricht was in Python eine Liste ist (Sachunterschjied scheint mir der das Listen unterschiedliche Datentypen zulassen, ein Array aber immer nur einen Datentyp), aber so ganz klar bin ich mir nicht ob man ein Array vielleicht auch als Tupel verstehen könnte.
In Python hast Du Listen und Tuple, die dann wohl von Starbasic in Array umgewandelt werden. Beim Programmieren muß man sehr exakt arbeiten, weil ein Computer versteht gar nichts mehr, wenn man nur leicht abweicht.
Ja, diese Kritik ist völlig berechtigt, aber bitte sieh es mir als Python-Anfänger nach, das ich versucht habe mich 'irgendwie' auszudrücken, weil mir Python-spezifische Begriffe noch nicht so geläufig sind.
Wenn Du keine Tuple willst, darfst Du keine Tuple erzeugen, sondern darfst nur row[0] in die Liste packen: [...]
Danke, das liefert das von mir gewünschte Ergebnis.

Kannst Du mirt bitte noch "cursor.fetchall()" vs. "cursor" erklären? Bisher glaubte ich das "fetchall" sei für das 'Einlesen' aller Datensätze verantwortlich (also quasi zeilenbezogen) aber es scheint sich wohl auf alle Spalten zu beziehen?


Gruß
Stephan
Sirius3
User
Beiträge: 17710
Registriert: Sonntag 21. Oktober 2012, 17:20

`cursor.fetchall` und `cursor` machen hier keinen Unterschied. Das hat nichts damit zu tun, ob Du nun eine Spalte oder viel hast.

`cursor` ist schon ein iterierbares Objekt, mit dem man über alle Ergebnisse iterieren kann, das fetchall ist daher nicht nötig, das nimmt nur alle Ergebnisse und packt sie in eine Liste. Da Du aber eh eine Listcomprehension benutzt, ist die explizite Liste überflüssig.
Benutzeravatar
__blackjack__
User
Beiträge: 13003
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Stephan_2021: Im Grunde musst Du die gleiche Operation, die Du in jetzt hinterher in StarBasic machst, halt vorher schon in Python machen. Also auf das einzige Element in der Sequenz zugreifen, in der der Datensatz steckt.

Der Zugriff erfolgt in BASIC über runde Klammern und den Index des Elements, also hier die 0. In Python sind das eckige Klammern und der Index.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Benutzeravatar
frogi001
User
Beiträge: 15
Registriert: Samstag 17. März 2018, 00:35

Hallo,
kann man sagen, dass die Aufgabe darin besteht, aus:

Code: Alles auswählen

ArrayA(Arryx(12,13,14),Arrayy(28,29),Arrayz(17))
ein

Code: Alles auswählen

ArrayA(12,13,14,28,29,17)
zu machen?
Viele Grüße
HS
Antworten