sqlite3.OperationalError: unable to open database file

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
Pyvin
User
Beiträge: 5
Registriert: Donnerstag 22. August 2019, 12:45

Hi Leute,

hab mich nun mal endlich registriert :P. Bin vom Status noch Anfänger nur vorweg.

Ich möchte für mein Projekt eine Datenbank (.db) mit Python abrufen, soll wie folgt aussehen.


from tkinter import *
import sqlite3


con = sqlite3.connect('\Desktop\python_work\RezegDBBench\RezegerDB.db')
cursor = con.cursor()
rezabfr = cursor.execute("SELECT * FROM ZutatenLM")

def showrezept():

return rezabfr


root = Tk()
root.geometry("400x200")

Label1 = Label(root)
button = Button(root, text='Zeige Lebensmittel', width=25, command=showrezept)

button.pack()
Label1.pack()

con.close()

root.mainloop()


Ich weiß das ich meist auf die Funktionen vom Editor zurückgreife, dennoch sollte es eig Funktionieren.

Hab schon das Forum und Google durchsucht und kann Berechtigung auf APpdata sowie, Aktualität Python etc. ausschließen.

Vielen Dank für Tipps und Hilfen
__deets__
User
Beiträge: 14542
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das ist kein gueltiger Pfad. Und wenn es einer waere, wuerdest du Probleme bekommen, weil der Backslash ein reserviertes Zeichen ist, dass du escapen musst. Oder du benutzt raw-Strings. Oder noch einfacher / stattdessen, das geht auch.
Benutzeravatar
__blackjack__
User
Beiträge: 13111
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Pyvin: Du vermischt da auch ziemlich unübersichtlich Datenbankcode mit GUI-Code. Warum steht das schliessen der Datenbankverbindung mitten um GUI-Code?

Sternchen-Importe sind Böse™. Tkinter wird üblicherweise per ``import tkinter as tk`` importiert und dann per ``tk.Button`` usw. auf die Objekte in dem Modul zugegriffen.

Namen schreibt man in Python klein_mit_unterstrichen. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (MixedCase). `Label1` sollte also `label1` heissen, beziehungsweise nur `label`, denn man nummeriert keine Namen. Das ist in fast allen Fällen ein Zeichen, dass man sich entweder bessere Namen suchen oder gar keine Einzelnamen sondern eine Datenstruktur verwenden sollte. Meistens ist das dann eine Liste. Hier ist aber einfach nur der Name schlecht gewählt.

Namen sollten auch nicht kryptisch abgekürzt werden. `connection` statt `con` und statt `rezabfr`, äh, da geht es dann schon los: ich habe keine Ahnung was mir diese Buchstabenkombination sagen will. Zumal die `execute()`-Methode laut DB 2.0-API-Dokumentation keinen definierten Rückgabewert hat.

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

Funktionen und Methoden bekommen alles was sie ausser Konstanten benötigen als Argument(e) übergeben. `showrezept()` dürfte also gar nicht einfach so auf `rezabfr` zugreifen können, denn auf Modulebene sollte es keine Variablen geben. Die Funktion ist aber sowieso nicht sinnvoll, denn die GUI-Hauptschleife, von der aus die Funktion aufgerufen wird wenn der Benutzer die Schaltfläche klickt, erwartet keinen Rückgabewert und macht damit auch nichts.

Bei SQL sollte man bei SELECT auch kein * verwenden, sondern explizit hinschreiben was man aus der Tabelle abfragen möchte. Dann weiss der Leser des Quelltextes was er da erwarten kann, und das Programm bleibt robust bei Veränderungen der Spaltenreihenfolge oder Anzahl. Beziehungsweise lassen sich Codestellen dann leichter finden und anpassen.

Edit: Ungetestet:

Code: Alles auswählen

#!/usr/bin/env python3
from contextlib import closing
from functools import partial
from pathlib import Path
import sqlite3
import tkinter as tk


def showrecipe(label, rows):
    label["text"] = str(rows)


def main():
    with closing(
        sqlite3.connect(
            Path.home()
            / "Desktop"
            / "python_work"
            / "RezegDBBench"
            / "RezegerDB.db"
        )
    ) as connection:
        with closing(connection.cursor()):
            cursor.execute("SELECT * FROM zutatenlm")
            rows = cursor.fetchall()

    root = tk.Tk()
    root.geometry("400x200")

    label = tk.Label(root)
    label.pack()
    button = tk.Button(
        root,
        text="Zeige Lebensmittel",
        width=25,
        command=partial(showrecipe, label, rows),
    )
    button.pack()

    root.mainloop()


if __name__ == "__main__":
    main()
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Antworten