SQLite erste Tests (Ticketsystem)

Stellt hier eure Projekte vor.
Internetseiten, Skripte, und alles andere bzgl. Python.
Jankie
User
Beiträge: 592
Registriert: Mittwoch 26. September 2018, 14:06

Habe jetzt noch ergänzt, dass ein Admin einen anderen User über den Namen auch zu einem Admin machen kann und dass ein Admin die Tickets von allen Usern sehen kann.

Code: Alles auswählen

def make_user_to_admin(connection, user_name):
    user_exists = connection.cursor().execute("SELECT EXISTS(SELECT 1 FROM user WHERE user_name = ?)", (user_name,)).fetchone()[0]
    if user_exists:
        connection.cursor().execute("UPDATE user SET admin = ? WHERE user_name = ?",(True, user_name))
        connection.commit()
        return True
    else:
        return False

Code: Alles auswählen

def show_tickets(connection, user_id):
    if is_admin(connection, user_id):
        return connection.cursor().execute("SELECT id, author_id, topic, content FROM ticket").fetchall()
    else:
        return connection.cursor().execute("SELECT id, author_id, topic, content FROM ticket WHERE author_id = ?",(user_id,)).fetchall()
Da aber die Funktion dass man jemanden zum Admin machen kann nur für Admins sichtbar sein soll, habe ich Probleme mit der Menuesteuerung. Wie macht man das am besten? Habe es jetzt mal so versucht:


Wird im main() aufgerufen:

Code: Alles auswählen

def print_menue(connection, user_id):
    while True:
        print("\nWas möchtest du tun:\n")
        print("1 - Ticket erstellen")
        print("2 - Meine Tickets ansehen")
        print("3 - Abmelden")
        print("4 - Account löschen")
        if is_admin(connection, user_id):
            print("5 - Adminrecht an User geben")
        menue_choice = int(input("\n> "))
        if menue_choice in range(1,6):
            return menue_choice
        else:
            print("Falsche Eingabe!\n")
Sirius3
User
Beiträge: 17712
Registriert: Sonntag 21. Oktober 2012, 17:20

Die Tatsache dass execute auch einen Cursor zurückliefert, sollte man nicht verwenden. Das ist nicht Teil der offiziellen DB-Schnittstelle in Python.
Ein vorheriges Abfragen ist auch gar nicht nötig, weil UPDATE einfach nichts macht, wenn der User nicht existiert.

Code: Alles auswählen

def make_user_to_admin(connection, user_name):
    cursor = connection.cursor()
    cursor.execute("UPDATE user SET admin = ? WHERE user_name = ?", (True, user_name))
    return cursor.rowcount != 0
die Existenz kann man auch in Python abfragen:

Code: Alles auswählen

def admin_exist(connection):
    cursor = connection.cursor()
    cursor.execute("SELECT 1 FROM user WHERE admin = ?", (True,))
    return cursor.fetchone() is not None
Jankie
User
Beiträge: 592
Registriert: Mittwoch 26. September 2018, 14:06

Genau weil es ja nichts zurückgibt habe ich die Abfrage da noch rein gemacht. Da sonst der Benutzer keine Rückmeldung bekommt ob sein vorhaben geglückt ist oder nicht. Aber da scheint mir deine Lösung besser zu sein, danke :)

Meinst du mit "Die Tatsache dass execute auch einen Cursor zurückliefert, sollte man nicht verwenden. Das ist nicht Teil der offiziellen DB-Schnittstelle in Python." dass ich vorher connection.cursor() an eine variable binden soll und dann cursor.execute() benutzen soll? Habe den Satz nicht ganz verstanden.
Benutzeravatar
__blackjack__
User
Beiträge: 13005
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Jankie: `cursor.execute()` gibt ”nichts” zurück. Bei `sqlite3` wird da zwar der Cursor zurückgegeben, das ist aber nicht garantiert, weil das nicht in der DB API V2-Dokumentation steht. Du kannst da also nicht einfach Cursor-Methoden auf dem Ergebnis aufrufen.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Jankie
User
Beiträge: 592
Registriert: Mittwoch 26. September 2018, 14:06

Also muss ich wenn ich das richtig verstehe statt:

Code: Alles auswählen

def show_tickets(connection, user_id):
    if is_admin(connection, user_id):
        return connection.cursor().execute("SELECT id, author_id, topic, content FROM ticket").fetchall()
    else:
        return connection.cursor().execute("SELECT id, author_id, topic, content FROM ticket WHERE author_id = ?",(user_id,)).fetchall()
besser

Code: Alles auswählen

def show_tickets(connection, user_id):
    cursor = connection.cursor()
    if is_admin(connection, user_id):
        cursor.execute("SELECT id, author_id, topic, content FROM ticket")
        return cursor.fetchall()
    else:
        cursor.execute("SELECT id, author_id, topic, content FROM ticket WHERE author_id = ?",(user_id,))
        return cursor.fetchall()
machen?
Sirius3
User
Beiträge: 17712
Registriert: Sonntag 21. Oktober 2012, 17:20

Besser:

Code: Alles auswählen

def show_tickets(connection, user_id):
    cursor = connection.cursor()
    if is_admin(connection, user_id):
        cursor.execute("SELECT id, author_id, topic, content FROM ticket")
    else:
        cursor.execute("SELECT id, author_id, topic, content FROM ticket WHERE author_id = ?",(user_id,))
    return cursor.fetchall()
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Und noch besser muss der immer gleiche Code (cursor.fetchall()) nach dem if kommen. Und eigentlich kann man auch noch die Query vereinheitlichen.

Code: Alles auswählen

sql = "SELECT id, author_id, topic, content FROM ticket"
arguments = ()
if not is_admin(connection, user_id):
        sql += " WHERE author_id = ?"
        arguments = (user_id,)
cursor.execute(sql, arguments)
return cursor.fetchall()
Wobei da ggf. auch besser gleich zu SQLAlchemy gegriffen wird, der macht das dann fuer einen.
Benutzeravatar
__blackjack__
User
Beiträge: 13005
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Stichwort SQLAlchemy: Wenn man das über `Table`-Objekte macht, also einfach nur um SQL per Hand schreiben zu vermeiden, könnte das so aussehen (ungetestet):

Code: Alles auswählen

    query = ticket_table.select()
    if not is_admin(user_table, user_id):
        query = query.where(ticket_table.c.user_id == user_id)
    return query.execute().fetchall()
Und wenn man das ORM verwendet, so (ungetestet):

Code: Alles auswählen

    query = session.query(Ticket)
    if not user.admin:
        query = query.filter_by(author=user)
    return query.all()
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Antworten