Ich versuche, eine einfache SELECT-Abfrage in einer MySQL-Datenbank (MariaDB) in Python 3 auszuführen.

Ich bekomme sehr seltsame Fehler

        query = (
            'SELECT user_id, user_password_hash, user_password_salt '
            'FROM users '
            'WHERE user_username = "%s"'
        )

        print(f'Trying login, username {username}, password {password}')

        try:
            cursor = self.connection.cursor(prepared=True)
            cursor.execute(query, (username,))

            results = cursor.fetchone()

            print(results)
            ...

        except Error as e:
            print('Error in login query: ' + str(e))
            raise e

Das Ausführen dieses Codes gibt mir den folgenden Fehler: Error in login query: 1210: Incorrect number of arguments executing prepared statement

Ich verstehe nicht - es erfordert ein Argument, und ich habe es ein Argument gegeben. Das Entfernen des Kommas im Tupel in execute() behebt dieses Problem nicht.

Wenn ich jetzt die Anführungszeichen aus der Abfrage entferne, wird ein ganz anderer Fehler angezeigt:

        query = (
            'SELECT user_id, user_password_hash, user_password_salt '
            'FROM users '
            'WHERE user_username = %s'
        )
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x9b in position 0: invalid start byte

The above exception was the direct cause of the following exception:

SystemError: <class 'UnicodeDecodeError'> returned a result with an error set

Die Tabelle verwendet utf8mb4, daher sollte dies kein Problem sein.

Außerdem funktioniert das Ausführen von SELECT * FROM users WHERE user_username="jeff" in der MySQL-Konsole einwandfrei.

Dies sollte eine wirklich triviale Frage sein, aber ich habe absolut keine Ahnung, was los ist - jede Hilfe wäre sehr dankbar.

BEARBEITEN: Beim Experimentieren in einem isolierten Python-Prozess habe ich das Problem reproduziert, indem ich Folgendes ausgeführt habe:

import mysql.connector

conn = mysql.connector.connect(host="localhost",
                               database="lucidlab",
                               user="lucidlab",
                               password="lucidlab")

cur = conn.cursor()
cur.execute("SELECT * FROM users WHERE user_username='jeff'")

results = cur.fetchall() # ERROR
print(results)

Dies lässt mich denken, dass es vielleicht ein Problem mit der Datenbankcodierung ist?

EDIT: Ich habe das Problem gelöst. Bitte sehen Sie meine Antwort unten.

1
William Osborne 19 Feb. 2020 im 15:56

3 Antworten

Versuchen Sie es mit doppelten Anführungszeichen:

    query = ("SELECT user_id, user_password_hash, user_password_salt "
        "FROM users "
        "WHERE user_username = %s"
    )

Oder dreifache Zitate:

    query = ("""SELECT user_id, user_password_hash, user_password_salt 
        FROM users 
        WHERE user_username = %s"""
    )

0
Nox 19 Feb. 2020 im 13:16

query = """SELECT user_id, user_password_hash, user_password_salt FROM users WHERE user_username = %s"""

Verwenden Sie dies wird es funktionieren ..

0
Aniket singh 19 Feb. 2020 im 16:36

Ich habe das Problem gefunden. Um dies zu beheben, musste man sich das Schema ansehen, das ich leider nicht nach der Lektion gelernt hatte.

Mein Schema enthielt Folgendes:

CREATE TABLE users (
...
  user_password_hash BINARY(20) NOT NULL,
  user_password_salt BINARY(20) NOT NULL,
...
);

Durch Ausführen einer SELECT * FROM users... - Abfrage jeglicher Art werden diese Binärdaten abgerufen, die Python hilfreich (!) Sofort in eine UTF-8-Zeichenfolge konvertiert ... was fehlschlägt, da das Salt Bytes sind, aus denen Bytes erzeugt werden os.urandom().

Ich habe dies behoben, indem ich stattdessen sha256_crypt aus der passlib Bibliothek verwendet und meine codierte Hash + Salt-Kombination als CHAR(77) gespeichert habe.

Vielen Dank an diejenigen, die geholfen haben - leider habe ich zu eng über das Problem nachgedacht und deshalb meine Frage als solche formuliert.

1
William Osborne 20 Feb. 2020 im 20:01