QtSql.QSqlRelationalTableModel

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
alpi
User
Beiträge: 8
Registriert: Mittwoch 18. Mai 2022, 06:04

Hallo liebes Community,

ich bin ein blutiger Anfänger und deshalb hoffe ich, dass mir jemand helfen kann.

Folgendes: Ich möchte aus einer Datenbank alle daten aus einer spalte zurück bekommen bzw. auslesen, damit ich überprüfen kann, ob zum Beispiel in der Spalte Email eine bestimmte Email vorhanden ist.
Hier mal der Code:



from operator import index
from PySide6.QtWidgets import QApplication, QMainWindow
from userpasswort.xy import Ui_MainWindow
from userpasswort.bu.oo import Ui_alper
from PySide6 import QtSql





class fm(QMainWindow, Ui_alper):
def __init__(self):
super().__init__()


self.setupUi(self)
self.newaccount.clicked.connect(self.weiter)




def weiter(self):
main.show()



class Main(QMainWindow, Ui_MainWindow):
def __init__(self):
super().__init__()



self.setupUi(self)

self.offene = QtSql.QSqlRelationalTableModel()
self.offene.setTable('info')
self.continue_2.clicked.connect(self.datenbank)



#self.leer.setModel(self.offene) # damit die
#self.leer.setItemDelegate(QtSql.QSqlRelationalDelegate())



def datenbank(self):


model = self.offene
query = QtSql.QSqlQuery()






query.exec( "SELECT email FROM info ")

query.first()
print(query.value(0)) #hier bekomme ich die Korrekte Email Adresse ausgegeben
print(query.value(1)) #hier bekomme ich None










model.select()





db = QtSql.QSqlDatabase.addDatabase('QSQLITE')
db.setDatabaseName('userpasswort.sqlite')



app = QApplication()
main = Main()



mf= fm()
mf.show()


app.exec()


Wenn ich den Code so ausführe bekomme ich zwar die erste Email Adresse korrekt zurück aber die zweite nicht.
Mit WHERE würde ich es zwar hinbekommen aber dann musste ich jedes mal, nach der ID-Nummer nachschauen und den Code anpassen.
Wie kann ich die zweite Spalte ausgeben?
Vielen Dank schonmal!
Benutzeravatar
noisefloor
User
Beiträge: 3843
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,
Ich möchte aus einer Datenbank alle daten aus einer spalte zurück bekommen bzw. auslesen, damit ich überprüfen kann, ob zum Beispiel in der Spalte Email eine bestimmte Email vorhanden ist.
Das ist doch zu umständlich. Wenn du sowas wie `SELECT email FROM tabelle WHERE email = 'die_gesuchte_adresse';` kannst du die Arbeit direkt in der Datenbank machen. Wenn du ein leeres Ergebnis bekommst ist die Adresse nicht vorhanden.
SELECT email FROM info
Liefert nur eine Spalte zurück - wenn du mehr Spalten willst musst du das bei SELECT mit angeben.

Gruß, noisefloor
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@alpi: Allgemeine Anmerkungen zum Quelltext: `operator.index` wird importiert, aber nirgends verwendet.

Namen sollten keine kryptischen Abkürzungen enthalten oder gar nur daraus bestehen. `oo`, `bu`, und `xy` für Modul- oder Paketnamen geht gar nicht. Auch `fm` für einen Klassennamen nicht. Und das Exemplar was davon erstellt wird, heisst dann `mf`‽ Namen sollen dem Leser vermitteln was die Werte dahinter in dem Programm bedeuten, und nicht zum Rätseln zwingen.

Namen werden in Python klein_mit_unterstrichen geschrieben. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (PascalCase). Wobei die Namen von Klassen in der Regel ”Dinge” im weitesten Sinne beschreiben, und Funktionen und Methoden Tätigkeiten. Damit man weiss was die machen, und um sie von eher ”passiven” Werten unterscheiden zu können. `datenbank()` ist also kein guter Methodenname, weil das keine Tätigkeit ist. Das wäre ein guter Name für das Attribut das tatsächlich die Datenbank repräsentiert, statt das `offene` zu nennen, was irgendwie unvollständig klingt.

Da ist eine recht willkürlich aussehende Verteilung von Leerzeilen in dem Quelltext.

Auf Modulebene sollte nur Code stehen der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst.

Wenn man das macht, dann kann `fm.weiter()` nicht mehr einfach so magisch auf `main` zugreifen, was gut ist, denn Funktionen und Methoden sollten alles was sie ausser Konstanten benötigen, als Argument(e) übergeben bekommen. `main` ist auch inhaltlich wohl eher falsch, oder ist das Fenster zum hinzufügen eines Benutzers tatsächlich das Hauptfenster? Was ist dann `mf`?

Die `fm.weiter()`-Methode ist überflüssig, denn die wird ohne Argumente aufgerufen und ruft dann ihrerseits bloss eine andere Methode ohne Argumente auf. Da kann man auch gleich das Signal mit dieser anderen Methode verbinden, statt mit `weiter()`.

Man generiert aus den *.ui-Dateien keinen Quelltext. Man kann die zur Laufzeit direkt laden. Problem ist das man sich das bei PySide offenbar immer noch selber basteln muss — da gibt's Beispiele für im Netz. Warum die nicht gleich selbst so etwas wie PyQt's `loadUi()` anbieten ist mir ein Rätsel.

`QSqlRelationalTableModel` wird nicht verwendet, kann also weg.

Code: Alles auswählen

#!/usr/bin/env python3
from pathlib import Path

from PySide6.QtSql import QSqlDatabase, QSqlQuery
from PySide6.QtWidgets import QApplication, QMainWindow

SELF_PATH = Path(__file__).parent


class ThisNeedsABetterName(QMainWindow):
    def __init__(self, next_window):
        super().__init__()
        loadUi(SELF_PATH / "alper.ui", self)
        self.newaccount.clicked.connect(next_window.show)


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        loadUi(SELF_PATH / "mainwindow.ui", self)
        self.continue_2.clicked.connect(self.name_that_relfects_what_this_does)

    @staticmethod
    def name_that_relfects_what_this_does():
        query = QSqlQuery()
        query.exec("SELECT email, name_der_anderen_spalte FROM info")
        if query.first():
            print(query.value(0))
            print(query.value(1))
        else:
            print("Kein Eintrag gefunden.")


def main():
    QSqlDatabase.addDatabase("QSQLITE").setDatabaseName(
        SELF_PATH / "userpasswort.sqlite"
    )

    app = QApplication()

    main_window = MainWindow()
    this_needs_a_better_name = ThisNeedsABetterName(main_window)
    this_needs_a_better_name.show()

    app.exec()


if __name__ == "__main__":
    main()
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Klassennamen werden nach Konvention mit GroßemAnfangsbuchstaben geschrieben, `fm´ ist aber auch zu kurz und nichts-sagend für eine Klasse. Besondern interessant ist, dass die Instanz der Klasse fm dann mf genannt wird. Tue Dir einen Gefallen und benutze sprechende Namen.
Die vielen Leerzeilen machen den Code schwer lesbar. Innerhalb einer Funktion dürfen nicht mehr als 1 Leerzeile hintereinander stehen, zwischen Funktionen sind es zwei.
Es sieht so aus, als ob Du die .ui-Dateien in Python-Code umgewandelt hast. Das macht man nicht, sondern lädt ui-Dateien per load_ui.

Dein SELECT fragt genau ein Feld ab, warum wundert es Dich, dass es kein zweites Feld gibt und value(1) None liefert?

Benutze keine globalen Variabeln. Die letzten paar Zeilen gehören auch in eine Funktion, die üblicherweise `main` genannt wird.
Antworten