Вот способ сделать именно то, что вы просили - выяснить, является ли данный 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':"[email protected]"},
{'username':"Billy", 'email':"[email protected]"},
{'username':"Charles", 'email':"[email protected]"},
{'username':"Dick", 'email':"[email protected]"},
{'username':"Emily", 'email':"[email protected]"},
{'username':"Faramir", 'email':"[email protected]"},
)
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", "[email protected]"
после создания базы данных, как выше, это поможет вам sqlite3.IntegrityError:
>>> conn.execute("""INSERT INTO users (username, email)
... VALUES ("Alice", "[email protected]");""")
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", "[email protected]");""")
except sqlite3.IntegrityError:
print ("Username 'Alice' was already taken.")
Кстати, будьте очень осторожны с использованием функций верхнего и нижнего регистра. Имеет ли значение "Главное в новостях".lower()
то, что вы думаете, что это значит?
Поскольку вы упоминаете это на веб-приложение, я просто напоминаю вам хранить ваши пароли salted hashes of the password, using unique salts for each user (не как обычный текст!), А также для защиты от инъекции SQL, используя (?,?,?,?,...)
заполнители для запросов SQL , а не метод интерполяции строк (%s,%s) % (var1, var2)
.
процитировать sqlite3 documentation:
Usually your SQL operations will need to use values from Python variables. You shouldn’t assemble your query using Python’s string operations because doing so is insecure; it makes your program vulnerable to an SQL injection attack.
Instead, use the DB-API’s parameter substitution. Put ? as a placeholder wherever you want to use a value, and then provide a tuple of values as the second argument to the cursor’s execute() method. (Other database modules may use a different placeholder, such as %s or :1.) For example:
Если вы не сделаете этого, то кто-то может запросить имя пользователя Robert Menzies; DROP TABLE users;
с hilarious results.
Чтобы сохранить память, рассмотрите возможность замены 'fetchall()' на 'fetchone()'. – Dikei