Поиск и сравнение баз данных SQLite / Python - PullRequest
4 голосов
/ 19 марта 2012

На данный момент у меня есть база данных, которая содержит имя пользователя, пароль и т. Д. Я хочу заглянуть в базу данных, чтобы проверить, есть ли там дубликаты.

con = lite.connect('userInfo.db')
with con:
    cur = con.cursor()
    cur.execute("SELECT * FROM Users WHERE LOWER(Username) = LOWER(?)", (newID,))
    rows = cur.fetchall()
    if len(rows)!=0:
        return "Duplicate detected"

Вот мой код на данный момент. newID - это новое имя, и я хочу проверить, существуют ли какие-либо записи в базе данных с таким же именем.

Мой вопрос - хорошая ли идея, как я это делаю в своем коде? В основном меня интересует мой подход. Должен ли я использовать что-то, кроме fetchall()?

Спасибо за ваше время! :) Постскриптум Это для веб-приложения.

Ответы [ 2 ]

5 голосов
/ 19 марта 2012

Вот способ сделать именно то, что вы просили - узнать, существует ли данный username:

import sqlite3
conn = sqlite3.connect(":memory:")
conn.execute ("""
              CREATE TABLE users (
                  uid INTEGER PRIMARY KEY AUTOINCREMENT,
                  username TEXT UNIQUE,
                  email TEXT UNIQUE );
             """)

test_users = (
    {'username':"Alice",    'email':"Alice@mail.com"},
    {'username':"Billy",    'email':"Billy@mail.com"},
    {'username':"Charles",  'email':"Charles@mail.com"},
    {'username':"Dick",     'email':"Dick@mail.com"},
    {'username':"Emily",    'email':"Emily@mail.com"},
    {'username':"Faramir",  'email':"Faramir@mail.com"},
)

for user in test_users:
    conn.execute("INSERT INTO users (username, email) VALUES (?,?)",
                 (user['username'],user['email'])
                )

result = conn.execute("SELECT COUNT(*) FROM users WHERE username='Alice'")
number_of_Alices = result.next()[0] # number_of_Alices will be 1

Поскольку все, что вам нужно, это COUNT, то этого достаточно.


На самом деле, вы не должны сами обеспечивать уникальность имен пользователей. Позвольте базе данных сделать это за вас, указав в качестве поля либо UNIQUE, либо PRIMARY KEY.

Если вы попытаетесь вставить "Alice", "alice@wonderland.com" после создания базы данных, как описано выше, вы получите sqlite3.IntegrityError:

>>> conn.execute("""INSERT INTO users (username, email)
...                     VALUES ("Alice", "alice@wonderland.com");""")
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
sqlite3.IntegrityError: column username is not unique

Чтобы обнаружить это, попробуйте запустить INSERT и определить, не работает ли он.

try:
    conn.execute("""INSERT INTO users (username, email)
                    VALUES ("Alice", "alice@wonderland.com");""")
except sqlite3.IntegrityError:
    print ("Username 'Alice' was already taken.")

Кстати, будьте очень осторожны с использованием функций верхнего / нижнего регистра. "Главное в новостях".lower() означает, что вы думаете, что значит?


Поскольку вы упоминаете, что это для веб-приложения, я просто напомню, что вы должны хранить ваши пароли как соленые хэши паролей, используя уникальные соли для каждого пользователя (никогда как обычным текстом!) и защититься от внедрения SQL с помощью заполнителей (?,?,?,?,...) для запросов SQL, а не (%s,%s) % (var1, var2) метода интерполяции строк.

Цитировать документацию sqlite3 :

Обычно для ваших операций SQL нужно использовать значения из Python переменные. Вы не должны собирать ваш запрос, используя строку Python операции, потому что это небезопасно; это делает вашу программу уязвимы для атаки SQL-инъекцией.

Вместо этого используйте подстановку параметров DB-API. Положил ? как заполнитель везде, где вы хотите использовать значение, а затем предоставить кортеж значений в качестве второго аргумента метода execute () курсора. (Другие модули базы данных могут использовать другой заполнитель, такой как% s или : 1.) Например:

Если вы этого не сделаете, кто-то может запросить имя пользователя Robert Menzies; DROP TABLE users; с веселыми результатами .

0 голосов
/ 19 марта 2012

Почему бы не установить поле в SQLite на уникальное, что в первую очередь предотвратит повторяющиеся записи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...