Seite 1 von 1

Befehle aus Datenbank ausführen

Verfasst: Montag 21. Dezember 2015, 12:25
von Landario
Servus,

Ich finde auch nach etlichen Stunden nicht wirklich etwas das mich weiterbringt, vielleicht hat ja jemand eine Dokumentation parat und kann mir helfen.

Durch Zufall sollen verscheidene definierte Befehle (Bewegungen an einem Modell) ausgeführt werden. Diese Befehle stehen in einer Datenbank. Über random wird eine Zahl generiert die der ID der zufälligen Bewegung entspricht.

Die Datenbank sieht im Prinzip so aus:

Code: Alles auswählen

id     |      name        |      code
1          eins                     Befehl1
2          zwei                    Befehl2
3          drei                     Befehl3



Minimalbeispiel meines Programmes soweit:

Code: Alles auswählen

import random
import time
import os, sys, sqlite3

connection = sqlite3.connect("database.db")
cursor = connection.cursor()

random.seed()

for x in range (99):

    x = random.randint(1,10)
    print (x)

    cursor.execute('SELECT * FROM movements WHERE id=?', (x,))
    for data in cursor:
        print(data[1])
        data[2] # Code der Ausgeführt werden soll
    print()
    time.sleep(2)

connection.close()
Zufällige Datensätze ausgeben über die Random-ID funktioniert tadellos. Nur wie wandel ich den Text aus der spalte code wieder in Phyton-Befehle um?


P.S.: Ich weiß das Befehle in ner Datenbank nicht das sicherste sind und Schindluder damnit getrieben werden kann. Aber für das Programm reicht das, und ist auch kein Sicherheitsrisiko.

Re: Befehle aus Datenbank ausführen

Verfasst: Montag 21. Dezember 2015, 13:07
von BlackJack
@Landario: Du solltest Dir trotzdem überlegen das *nicht* zu tun. Speicher die Bewegungen als Daten und interpretiere die dann. Das ist sicherer — in beiden Bedeutungen des Wortes: „safety“ und „security“. Und unabhängiger von Python ist es auch.

Wie sehen die möglichen ”Befehle” denn aus?

Anmerkungen zu Quelltext: `random.seed()` ist unnötig, kann sogar unter bestimmten Bedingungen zu weniger Zufall führen → weg damit.

`x` wird für mehrere Sachen verwendet. Wenn Du die Schleifenvariable nicht benötigst, dann könntest Du sie `_` nennen. Das ist eine übliche Konvention für Werte die nicht benötigt werden, denen man aus syntaktischen Gründen aber einen Namen geben muss.

Es ist nicht garantiert das IDs (Primärschlüssel) aufsteigende, lückenlose Werte haben. Ausserdem kann auch 0 oder negative Zahlen gültige IDs sein. Wenn Du IDs hast die grösser 10 sind, werden die Datensätze nicht mehr erfasst. Ich würde an der Stelle ja lieber alle IDs abfragen, oder falls die Daten nicht zu gross sind, gleich alle Datensätze, und dann mit `random.choose()` auswählen.

Wenn man einen Datensatz anhand seiner ID abfragt, dann braucht man nicht mit einer Schleife über die Ergebnisse iterieren sondern man holt sich genau diesen einen Datensatz mit `fetchone()`.

Re: Befehle aus Datenbank ausführen

Verfasst: Montag 21. Dezember 2015, 13:12
von noisefloor
Hallo,

Hint: bei den Build-In Funktionen gibt es zwei, die für dein Vorhaben in Frage kommen könnten. Warum du das aber _nicht_ machen solltest hat BlackJack schon ausgrführt :-)

Gruß, noisefloor

Re: Befehle aus Datenbank ausführen

Verfasst: Montag 21. Dezember 2015, 13:29
von BlackJack
@Landario: Die Importe `os` und `sys` werden nicht verwendet.

Bei Datenbankabfragen sollte man '*' vermeiden und besser alles das was man haben möchte explizit hinschreiben. Der Quelltext wird dann verständlicher und man bekommt keine Probleme wenn Tabellen erweitert werden oder Spalten umsortiert werden, oder bei der Abfrage mehr potentielle Spalten durch einen JOIN hinzukommen.

Das und die Bemerkungen vom letzten Beitrag führen dann zu (ungetestet):

Code: Alles auswählen

#!/usr/bin/env python
# coding: utf-8
from __future__ import absolute_import, division, print_function
import random
import sqlite3
import time
from contextlib import closing


def main():  
    with closing(sqlite3.connect('database.db')) as connection:
        cursor = connection.cursor()
        cursor.execute('SELECT name, code FROM movements')
        movements = cursor.fetchall()
    for _ in range(99):
        name, code = random.choice(movements)
        print(name, code)

        print()
        time.sleep(2)

if __name__ == '__main__':
    main()

Re: Befehle aus Datenbank ausführen

Verfasst: Montag 21. Dezember 2015, 13:31
von Landario
@BlackJack
Danke für die schnellen antworten, es handelt sich um Koordinaten die gesendet werden sollen.....langfristig sollen diese auch ohne Code in der Datenbank landen. Das mit den ID's ist mir bewusst, jedoch sind die Daten in dieser Tabelle alle statisch, also können nicht geändert, hinzugefügt, etc werden, somit ist die ID manuell vorgegeben und immer positiv von 1-soviel ich brauch. Es handelt sich bei dem Code nur um ein Minimalbeispiel Testprogramm....uneindeutige Variabeln werden noch ersetz. Aber ich räume mal etwas auf bevor ich nochmal was poste^^

In der Beta würde ich jedoch trotzdem gerne erstmal den Code direkt aus der Datrenbank laden und dies später beheben wenn ich mehr Zeit dafür habe (Bitte respektiert diese Entscheidung)

@noisefloor The evil eval? Hab durch Zufall den Befehl probiert da ich ihn aus PHP kenne und ich glaube der müsste es sein oder?

Re: Befehle aus Datenbank ausführen

Verfasst: Montag 21. Dezember 2015, 13:43
von Landario
The evil eval war die gesuchte Funktion, sobald das Grundgerüst steht wird aber darauf verzichtet und die Daten aus der DB interpretiert.

Code: Alles auswählen

eval()
Danke an alle (:

Re: Befehle aus Datenbank ausführen

Verfasst: Montag 21. Dezember 2015, 13:45
von Sirius3
@Landario: Du machst Dir lieber jetzt und später die doppelte Arbeit, als gleich ordentlich zu programmieren :evil: . Eine Funktion mit Parametern aus einer Datenbank aufzurufen ist definitiv weniger Aufwand als diese Funktion in die Datenbank zu schreiben und dann umständlich den Code aufzurufen.

Re: Befehle aus Datenbank ausführen

Verfasst: Montag 21. Dezember 2015, 13:51
von BlackJack
@Landario: Erfahrungsgemäss werden Sachen die man wissentlich unsauber löst, mit dem Vorsatz das zu ändern wenn man mal Zeit hat, so gut wie nie tatsächlich noch mal sauber gelöst. So etwas bleibt in der Regel für die Ewigkeit.

Re: Befehle aus Datenbank ausführen

Verfasst: Montag 21. Dezember 2015, 14:10
von noisefloor
Hallo,
Landario hat geschrieben: es handelt sich um Koordinaten die gesendet werden sollen
Aber dann macht `eval()` dort erst recht keinen Sinn. Lies' die Koordinaten aus und übergib' sie als Parameter an eine Funktionen. Dann ist es sauber. Und auch später wesentlich einfacher, von DB auf ein INI-File oder JSON oder so umzustellen.

Gruß, noisefloor

Re: Befehle aus Datenbank ausführen

Verfasst: Montag 4. Januar 2016, 15:42
von Landario
Es war ja nur zum testen , habe jetzt alles umgestellt und die Datenbanken sind wieder sicher :)