variable in sql befehl einbinden

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
Helge75HH
User
Beiträge: 5
Registriert: Mittwoch 27. Juli 2022, 19:24

Hallo,

ich bin gerade wieder dabei mich mehr mit Python zu beschäftigen und bin gerade an einem Punkt wo ich nicht mehr weiter komme!
Foldender code :

Code: Alles auswählen


 import mysql.connector

              db = mysql.connector.connect(
                     host="localhost",
                     user="root",
                     password="",
                     database="adressbuch"
                     )
              cursor = db.cursor()
              a = input("Suche nach Nachnamen: ")
              sql = "Select * From personen WHERE nachname LIKE + 'a+%'"
              #sql = "Select * From personen WHERE nachname LIKE 'm%'"
              cursor.execute(sql)
              for eintrag in cursor:
                  print(eintrag)


Ich möchte die variable a, bzw. den String den ich durch input() aufnehme in den Sql befehl einbinden!

Es soll dann sozusagen wie der auskommentierte sql-befehl( hier werden alle nachnamen mit m am anfang angezeigt ) sein und mir alle nachnamen ausgeben mit like + den wert aus a!

Ich habe jetzt echt schon stundenlang rumprobiert, aber komme nicht an Ziel.

Habe ich da iwelche denkfehler?

Ist das überhaupt so möglich oder gibt es da Eigenarten von Python oder SQL die ich im besonderen berücksichtigen muss?

Für Tipps, Anregungen etc. bin ich echt dankbar....

Gruß,

Helge
Benutzeravatar
pillmuncher
User
Beiträge: 1484
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

Statt stundenlang zu raten einfach einen Blick in die Dokumentation werfen:

https://dev.mysql.com/doc/connector-pyt ... elect.html

Mach das so, wie dort beschrieben, dann hast du auch keine Probleme wie dieses:
Bild
In specifications, Murphy's Law supersedes Ohm's.
Helge75HH
User
Beiträge: 5
Registriert: Mittwoch 27. Juli 2022, 19:24

Hallo,

danke für deinen tipp, der bringt mich leider nicht weiter, da ich vollen Zugang zur Datenbank habe also mit dem connector, das ist hier nicht das problem...

Vieleicht habe ich mich unverständlich ausgedrückt ich möchte zur laufzeit des Programms am Prompt eine Zeichenkett aufnehmen und diese in der variable a speichern. diese variable a möchte ich dann gerne in den SQl-befehl einbauen um die abfrage interaktiver zu gestalten. Ich möchte am prompt also z.b. den teilstring "Ma" eingeben und dann dieser wird in a gespeichert. Jetzt möchte ich den sql befehl so schreiben das alle nachnamen ausgebenen werden, die mit dem in a gespeicherten string beginnen! Bsp. sql = "Select * From personen WHERE nachname LIKE 'm%' , wobei hier das m ausgetauscht wird mit der variable a ! Es sollen dann nur nachnamen ausgegeben werden die mit "Ma" beginnen. Puh..... ich kann es nicht anders erklären , ich hoffe ihr habt verstanden was ich meine ? :-)

Also das einbauen der Variable a in den SQL-Befehl bekomme ich nicht hin. Daher die Frage, geht es überhaupt so wie ich es vorhabe?

Bin noch nicht so versiert mit Python bzw. SQL!

Gruß,

Helge
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

Du hast es nicht geschafft, über die Überschrift hinweg den sehr kurzen Artikel zu lesen?
We then execute the operation stored in the query variable using the execute() method. The data used to replace the %s-markers in the query is passed as a tuple: (hire_start, hire_end).
Das Prozent mußt Du in Python an Deinen String hängen.
Benutzeravatar
__blackjack__
User
Beiträge: 13116
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Anmerkungen zum Quelltext: Sowohl Datenbankverbindungen als auch Cursor-Objekte sollte man wieder schliessen. Am sichersten in dem man `contextlib.closing()` und die ``with``-Anweisung verwendet.

Tabellennamen sollten in der Einzahl geschrieben werden. Das sieht sonst in ER-Diagrammen komisch aus.

Der Code aus dem Ausgangsbeispiel sähe dann ungefähr so aus:

Code: Alles auswählen

#!/usr/bin/env python3
from contextlib import closing

import mysql.connector


def main():
    with closing(
        mysql.connector.connect(
            host="localhost", user="root", password="", database="adressbuch"
        )
    ) as db:
        answer = input("Suche nach Nachnamen: ")
        with closing(db.cursor()) as cursor:
            cursor.execute(
                "SELECT * FROM person WHERE nachname LIKE + 'answer+%'"
            )
            for row in cursor:
                print(row)


if __name__ == "__main__":
    main()
Ich persönlich greife ja immer schnell zu SQLAlchemy, auch wenn ich den ORM-Teil nicht verwende, sondern nur den Core-Teil. Das bügelt unterschiede zwischen den verschiedenen Datenbanken/Adaptern aus, beispielsweise wie Platzhalter aussehen müssen, oder ob es einen echten BOOLEAN-Typ gibt oder nicht. Und wenn man Abfragen zusammenbasteln muss, dann ist man da nicht mehr auf fehleranfällige Zeichenkettenoperationen angewiesen.

Code: Alles auswählen

#!/usr/bin/env python3
from sqlalchemy import MetaData, create_engine, select


def main():
    engine = create_engine("mysql://root@localhost/adressbuch")
    meta_data = MetaData()
    meta_data.reflect(engine)
    person_table = meta_data.tables["person"]

    answer = input("Suche nach Nachnamen: ")
    with engine.connect() as connection:
        for row in connection.execute(
            select(person_table).where(
                person_table.c.nachname.like(answer + "%")
            )
        ):
            print(row)


if __name__ == "__main__":
    main()
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Helge75HH
User
Beiträge: 5
Registriert: Mittwoch 27. Juli 2022, 19:24

Hallo Blackjack,

ich möchte mich erstmal bedanken für deine Mühe. Ich habe deinen code übernommen und mir das ganze nochmal angeschaut. Wenn ich das Programm ausführe, bekomme ich keine Fehlermeldung aber es wird auch kein einziger Datensatz aus der DB angezeigt. Ändere ich den Sql befehl auf "Select * From personen" ab werden mir alle Datensätze der Datenbank angezeigt! Ich habe das ganze sowohl in der Python Idle als auch in Pycharm getestet, bei beiden werden wie gesagt keine Fehler angezeigt , aber auch keine Datensätze.

Ich vermute das die for schleife nicht ausgeführt wird, ich habe noch ein print("Datenbankabfrage beendet") nach der for Schleife hinzugefügt, das wird auch ausgegeben!

Ich befürchte das es an den IDE´s liegt, aber meine Erfahrungen damit sind sehr beschränkt!

Danke dennoch für deine Hilfe,

Gruß,

Helge
Benutzeravatar
__blackjack__
User
Beiträge: 13116
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Helge75HH: Der erste Code funktioniert natürlich nicht. Der sollte das gleiche machen wie Dein erster Code, der ja auch nicht funktioniert hat. Wobei ich da ohne es auszuprobieren eigentlich eine Fehlermeldung von der Datenbank erwartet hätte, oder ist das für MySQL tatsächlich gültiges SQL‽ Ich hätte vermutet das ``+`` macht an der Stelle ein Problem.

Den zweiten Code hatte ich mit SQLite getestet und da funktioniert er. Wenn der mit MySQL nicht geht, müsste man schauen woran das liegt.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Helge75HH
User
Beiträge: 5
Registriert: Mittwoch 27. Juli 2022, 19:24

So,

jetzt habe ich es hinbekommen, dieser Code funktioniert erstmal :

Code: Alles auswählen


import mysql.connector

              connection = mysql.connector.connect(
                     host="localhost",
                     user="root",
                     password="",
                     database="adressbuch"
                     )
              cursor = connection.cursor()
              var1 = input("Suche nach Nachnamen: ")

              sql = "SELECT * FROM personen WHERE nachname LIKE '"+var1+"%' "

              cursor.execute(sql)
              result = cursor.fetchall()
              
              for row in result:
                  print(row)
                  print("-"*140)

              print("Datenbankabfrage beendet.")

              connection.close()




Gruß,

Helge
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

@Helge75HH: funktioniert nicht, wie hier schon vielfach geschrieben.

Code: Alles auswählen

#!/usr/bin/env python3
from contextlib import closing
import mysql.connector


def main():
    with closing(
        mysql.connector.connect(
            host="localhost", user="root", password="", database="adressbuch"
        )
    ) as db:
        surname = input("Suche nach Nachnamen: ")
        with closing(db.cursor()) as cursor:
            cursor.execute(
                "SELECT * FROM personen WHERE nachname LIKE %s", 
                (surname + "%", )
            )
            for row in cursor:
                print(row)


if __name__ == "__main__":
    main()
Helge75HH
User
Beiträge: 5
Registriert: Mittwoch 27. Juli 2022, 19:24

Hallo Sirius,

der zuletzt von mir gepostete Code funktioniert bei mir!

Ich wollte einfach nur nochmal meine Lösung präsentieren.

gruß,

Helge
Benutzeravatar
__blackjack__
User
Beiträge: 13116
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Helge75HH: Der ist trotzdem falsch, auch wenn er ”funktioniert”. Denn er ”funktioniert“ halt auch für little Bobby Tables, und das will man nicht. Zudem ist er potentiell ineffizient, weil ein Datenbankadapter die Werte eventuell gar nicht in das SQL (*sicher*) hinein formatiert, sondern SQL und Werte getrennt an die Datenbank übermittelt, und die Werte erst nach der Übersetzung von SQL-Quelltext in den internen Ablaufplan einsetzt. In dem Fall kann das SQL mit den Platzhaltern zusätzlich noch als Schlüssel in einen Cache mit Ablaufplänen verwendet werden, so dass sich bei mehrfachen gleichen Anfragen der Schritt SQL→Ablaufplan einsparen lässt.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Antworten