Liste definiert Database, Table, Alter Table und Insert / voll parametrisch

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
mischtkrabb
User
Beiträge: 5
Registriert: Montag 28. November 2022, 17:22

Ich möchte folgendes gern voll parametrisch erstellen:
- CREATE DATABASE
- CREATE TABLE
- ALTER TABLE
- INSERT INTO TABLE

Ausgang ist eine Liste, die ich jederzeit erweitern kann und mein Code sich entsprechend anpassen soll, ohne an mehreren Stellen manuell was ändern zu müssen. Theoretisch funktioniert das auch. Nur mein cursor.execute macht Probleme. Mit dem Cursor.execute als Kommentar funktioniert es einwandfrei. Nur sind dann meine Werte nicht "parametrisch":

Code: Alles auswählen

#!/usr/bin/python
import mysql.connector as mariadb
import datetime
import time
import requests

DB_server = '123.456.789.123' 
DB_user = 'user'
DB_passwort = 'passwort'
DB_name = 'Datenbank'
TAB_name= 'Tabelle'
liste = ["Name1", "Name2", "Name3"] #, "Name4","Name5","Name6"] # soll nach und nach ergänzt werden
url = "https://eine.url/mit/daten/"

def verbinden():
    con = mariadb.connect(
        host=DB_server,
        user=DB_user,
        passwd=DB_passwort,
    )
    return con

def DB_erstellen(cursor):
    anfang= "CREATE TABLE IF NOT EXISTS " +TAB_name +"(id int(11) NOT NULL AUTO_INCREMENT, Datum datetime NOT NULL, PRIMARY KEY (id))"
    cursor.execute("CREATE DATABASE IF NOT EXISTS {} DEFAULT CHARACTER SET 'utf8'".format(DB_name))
    cursor.execute("USE {}".format(DB_name))
    cursor.execute(anfang)
    print anfang

def alter_table(cursor):
        i=0
        zeichen=""
        while i < len(liste):
                zeichen = ("ALTER TABLE " +TAB_name +" ADD COLUMN IF NOT EXISTS " +liste[i] +" int NOT NULL;")
                i += 1
                print zeichen
                cursor.execute("USE {}".format(DB_name))
                cursor.execute(zeichen)

def befuellen(cursor,TAB_name,con):
    datum=datetime.datetime.now().replace(microsecond=0)
    werte=[]
    z=0
    value=""
    i = 0
    zeichen= ""
    format=""
    for i in liste:
        r = requests.get(url+str(i))
        text=r.text
        abfrage=text.isdecimal()
        if abfrage:
                zahl=int(text)
                werte.append(zahl)
                value += (",werte["+str(z)+"]")
                zeichen += (","+liste[z])
                format +=",%s"

        else:
                werte.append(0)
                value += (",werte["+str(z)+"]")
                zeichen += (","+liste[z])
                format +=",%s"

    sql = "INSERT INTO "+TAB_name+" (Datum" +zeichen+") VALUES (%s"+format+")"
    val = "(datum"+value+")"
    cursor.execute (sql, val)

########## so geht es 
##    cursor.execute(sql, (datum,werte[0],werte[1],werte[2]))

    con.commit() 

def main():
    con=verbinden()
    alter_table(cursor)
    befuellen(cursor,TAB_name,con)
    cursor.close()
    con.close()
    con.disconnect()


main() 
Ich habe inzwischen gelesen, dass man den Execute nicht als String zusammen basteln soll. Ich denke das ist auch das Problem. Aber leider bin ich Laie und ich hab keine Ahnung wie ich es besser machen könnte. Vielleicht habt ihr ja einen Tipp der mir weiter hilft. Vielen Dank ;-)
Benutzeravatar
sparrow
User
Beiträge: 4165
Registriert: Freitag 17. April 2009, 10:28

Man macht weder Table- noch Feldnamen flexibel in einem Programm. Wozu auch? Die Datenbankstruktur ist fest. Wenn sie das nicht ist, ist das mit hoher Wahrscheinlichkeit ein Fehler im Design.
Benutzeravatar
noisefloor
User
Beiträge: 3843
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

gerne liegt bei sowas der Designfehler der DB in nicht oder falsch genutzten Relationen bzw. in der fehlenden Normalisierung der Daten. Besonders, dass Tabellen dynamisch Spalten hinzugefügt werden sollen, ist ein Indiz dafür.

Oder, aber IMHO unwahrscheinlicher, man nutzt den falschen Datenbanktyp und möchte statt einer relationalen Datenbank eher eine spaltenorientierte Datenbank oder einen anderen Datenbanktyp aus der NoSQL Fraktion.

Gruß, noisefloor
mischtkrabb
User
Beiträge: 5
Registriert: Montag 28. November 2022, 17:22

ich bin Laie und kenn nichts anderes. habe eben mit einem befreundeten Programmierer telefoniert. der macht riesengroße Datenbanken mit Java ...ok ich versteh , dass er da einiges anders macht und meinen Weg in der Praxis keiner machen würde. mir reicht mein Weg aber vollkommen aus, wenn er funktionieren würde. Alles andere wäre für mich zu viel Aufwand.

Hätte ja sein können es erkennt jemand auf Anhieb warum ich folgende Fehlermeldung bekomme:

Code: Alles auswählen

mysql.connector.errors.ProgrammingError: 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '%s,%s,%s,%s)' at line 1
Benutzeravatar
noisefloor
User
Beiträge: 3843
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,
ich bin Laie und kenn nichts anderes.
Darum hast du doch hier gefragt und darum sagen wir dir ja auch, was du besser machen kannst. Oder erwartest du ernsthaft, dass dein suboptimaler Weg Unterstützung findet? Du willst doch _besser_ werden, nicht unter Mittelmaß stagnieren, oder?
Alles andere wäre für mich zu viel Aufwand.
Nein, eben _nicht_. Kannst du als "Laie" vielleicht noch nicht wirklich nachvollziehen, aber ein falscher DB Entwurf und besonders der Verzicht auf Relationen fällt dir sehr sicher irgendwann auf die Füße. Und das ist dann i.d.R. richtig viel Arbeit / Aufwand, das gerade zu rücken.

Wenn du eine relationale DB nutzen willst musst du dich halt zumindest ein bisschen damit beschäftigen. Dazu gehören Relationen und das Normalisieren von Daten. Man muss das für kleine Projekte / privat sicherlich bis zum Exzess machen, aber die erste Stufe macht in der Regel immer Sinn. Literatur gibt es dazu reichlich im Netz.

Was willst du denn speichern?

Gruß, noisefloor
mischtkrabb
User
Beiträge: 5
Registriert: Montag 28. November 2022, 17:22

Du willst doch _besser_ werden, nicht unter Mittelmaß stagnieren, oder?
ähm ja. aber ich wäre auch damit zufrieden wenns so läuft. hab ja 99% fertig. wenn ich das nun so mach wie man es besser macht, heißt das nur wieder stunden- oder tagelang googeln, ausprobieren usw.
Was willst du denn speichern?
ich will einfach nur alle 5 Minuten diverse Integer Werter (Zuschauer) von Webseiten holen.
mischtkrabb
User
Beiträge: 5
Registriert: Montag 28. November 2022, 17:22

Problem erkannt und gelöst.
cursor.execute (sql, val)
meine Variable val ist ein String, aber muss ein Tuple sein ! Nach umbauen auf Tuple läuft mein Code so wie ich mir das vorgestellt habe
Sirius3
User
Beiträge: 17712
Registriert: Sonntag 21. Oktober 2012, 17:20

Eingerückt wird in Python immer mit vier Leerzeichen pro Ebene. Nicht mal acht und mal vier.
Konstanten schreibt man komplett groß. Der Tabellenname ist bei dir eine Konstante. Den also variabel in den SQL Ausdruck zu formatieren ist absolut unnötig.
Statt eines einfachen insert-Ausdrucks mit fixen Feldnamen hast du eine 28 Zeilen Monsterfunktion geschrieben die niemand versteht. Glaubst du wirklich, dass das einfacher ist?
Benutzeravatar
noisefloor
User
Beiträge: 3843
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,
ich will einfach nur alle 5 Minuten diverse Integer Werter (Zuschauer) von Webseiten holen.
Dann hast du zwei Tabellen: einen, wo die Webseiten drin aufgelistet sind, Tabelle so definiert, dass jede Webseite nur genau 1x in der Tabelle vorkommen darf. Die zweite Tabelle hat die Spalte "Webseite" als Fremdschlüsselbeziehung zur Tabelle Webseite, eine Spalte "Zuschauerzahl" und, falls du es benötigst, eine dritte Spalte mit dem Datum/Uhrzeit, wenn der Zuschauerzahlwert abgelesen wurde. Fertig.

Dafür braust du ganz sicher keine variablen Tabellenbreiten und Namen.

Gruß, noisefloor
Benutzeravatar
sparrow
User
Beiträge: 4165
Registriert: Freitag 17. April 2009, 10:28

Weil das für viele Menschen in Einstieg verwirrend sein kann. Eine Table aus einer relationalen Datenbank hst erst einmal nichts mit einer Tabelle aus einer Tabellenkalkulation zu tun. Deshalb macht es gsr keinen Sinn dort Spalten zu variieren.
Hier wurde das Wort "Normalisierung" ja bereits genannt. Lies mal den entsprechenden Eintrag darüber bei Wikipedia. Der ist recht verständlich geschrieben.
mischtkrabb
User
Beiträge: 5
Registriert: Montag 28. November 2022, 17:22

Vielen Dank für eure ganzen Antworten die mich absolut null weitergebracht haben. Ich dachte das hier ist ein Python Forum und kein Forum für Datenbank Experten. Mag ja sein , dass ich vieles falsch mache mit meiner Datenbank. Für meine Zwecke ist das aber für mich mehr als ausreichend und ich hab keine Ahnung wie Profis sowas machen würden. Auch das Googlen der von euch vorgeschlagenen Wörtern bring mich null weiter, weil ich da nur Bahnhof und Abfahrt versteh. Ich habe keine Anomalien oder sonst was. Ich speichere Werte so ab wie ich das möchte und wie es mir logisch erscheint sowas zu tun. Ich hab nach einem Python Problem gefragt. Ein Problem auf das von euch keiner einging. Dabei war es nur ein falscher Datentyp bei meinen Werten...

Der Dank gilt meinem Kumpel, der sich telefonisch Zeit für mich nahm und dessen Hinweis mir geholfen hat das Problem zu lösen. Obwohl er den Code noch nicht mal kannte geschweige denn Ahnung von Python hat
Benutzeravatar
sparrow
User
Beiträge: 4165
Registriert: Freitag 17. April 2009, 10:28

Genau. Das ist ein Python-Forum. Deshalb haben wir dir auch erklärt, dass dein Entwurf in Python (und jeder anderen Programmiersprache) falsch ist.
Aber gut, dass du deinen Kumpel hast. Viel Erfolg :D
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

"Ich dachte, das waere ein Holzhackforum, und kein Forum fuer Amputationsexperten! Mag ja sein, dass ich mir schoen regelmaessig in die Schienenbeine hacke, aber das war hier nicht die Frage! Ich wollte nur wissen, wie ich meine Axt wieder scharf bekomme."

Hoffen wir mal dein Kumpel steht dir auch zur Seite, wenn der Fuss ab ist. Respektive dir deine Datenbank auf die Fuesse faellt.
Benutzeravatar
noisefloor
User
Beiträge: 3843
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

na ja, die fragst nach Hilfe, verweigerst dich aber gleichzeitig allen Antworten, die dir wirklich helfen. Da hättest du dir auch das Fragen schenken können. Ja, die Antworten haben nicht dein akutes Problem gelöst, hätte aber deine ganzen anderen, viel größeren Probleme in Bezug auf Python und Datenbankdesign gelöst. Das hat auch nichts mit "Profi" zu tun (bin ich auch nichts), sondern eher mit den Basics.

Gut, deine Entscheidung, dass alles zu ignorieren und dich zu verweigern, auch nur ein bisschen besser zu werden. Aber daran wirst du halt, wenn du weiter programmierst, immer wieder scheitern.

Gruß, noisefloor
Antworten