Python SQLite: IndexError: список индексов вне диапазона - PullRequest
0 голосов
/ 29 октября 2018
conn = database_connect()
if(conn is None):
    return None
cur = conn.cursor()
try:
    # Try executing the SQL and get from the database
    sql = """SELECT *
            FROM user
            WHERE user_id**strong text** =%s AND password =%s"""
    cur.execute(sql, (employee_id, password))
    r = cur.fetchone()# Fetch the first row
    rr = cur.fetchall()
    cur.close()                     # Close the cursor
    conn.close()                    # Close the connection to the db

except:
# If there were any errors, return a NULL row printing an error to the debug
    print("Error Invalid Login")
    cur.close()                     # Close the cursor
    conn.close()                    # Close the connection to the db
    return None

user_info = []
if rr is None:
    print("worry")
    return []

for n in rr:
    user_info.append(n)

test = {
    'info1': user_info[0],
    'info2': user_info[1],
    'info3': user_info[2],
    'info4': user_info[3],
}

return test

Вот мой код. Сначала реализуйте функцию входа в систему, а затем получите информацию о пользователе, но есть IndexError: list index out of range. Как мне это исправить?

1 Ответ

0 голосов
/ 29 октября 2018

Здесь:

r = cur.fetchone()# Fetch the first row
rr = cur.fetchall()

Вызов fetchone() будет занимать первую строку, поэтому rr будет содержать n-1 строк.

Кроме того, если в вашей базе данных разрешено дублирование user_id, у вас возникнет серьезная проблема с дизайном БД - является ли (предположительно) user_id первичным ключом или «именем пользователя» (логином), он действительно должен быть уникальным. Если это не так, то вы хотите изменить свою схему, и если она действительно уникальна, то, очевидно, ваш запрос может вернуть (максимум!) Только одну строку, и в этом случае гарантируется, что rr всегда будет пустым (так как Вы использовали первую строку с вызовом fetchone().

В качестве примечания отметим несколько возможных улучшений:

это:

for n in rr:
    user_info.append(n)

совершенно бесполезен - вы просто создаете поверхностную копию rr, а вместо этого работаете непосредственно с rr.

Тогда не думайте, что у вас всегда будет четыре строки в результате запроса, поэтому, по крайней мере, создайте свой test диктат динамически:

test = {}
# enumerate(seq) yields an index, value tuple
# for each value in `seq`.
for num, row in enumerate(rr, 1):
    key = "info{}.format(num)
    test[key] = row

или более кратко:

test = {"info{}".format(num):row for num, row in enumerate(rr, 1)}

Обратите внимание, что этот дикт не имеет большого значения по сравнению с rr - вместо числовых индексов у вас есть «информационные» ключи, и это все, так что вы можете просто использовать вместо него список rr.

И последнее, но не менее важное: ваше предложение try / exception слишком широкое (слишком много кода в блоке try), предложение исключением будет содержать очень ценную информацию об отладке (точное сообщение об ошибке и полный возврат) и, что еще хуже, Отображаемое сообщение об ошибке предполагает слишком много о том, что на самом деле происходит. На самом деле, у вас, вероятно, даже не должно быть здесь выражения "исключение" (по крайней мере, до тех пор, пока вы действительно не будете знать, какие ошибки могут быть здесь и правильно обработаны на этом этапе), поэтому лучше позволить распространению ошибки (чтобы вы получили полное сообщение об ошибке и трассировку ) и используйте предложение finally, чтобы закрыть ваше соединение:

sql = """SELECT *
        FROM user
        WHERE user_id**strong text** =%s AND password =%s"""

try:
    cur.execute(sql, (employee_id, password))
    r = cur.fetchone()# Fetch the first row
    rr = cur.fetchall()
finally:
    # this will always be executed whatever happens in the try block
    cur.close()                     # Close the cursor
    conn.close()                    # Close the connection to the db
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...