На этом шаге мы рассмотрим методы выполнения запросов к базе данных.
Согласно спецификации DB-API 2.0, после создания объекта соединения необходимо создать объект-курсор. Все дальнейшие запросы должны производиться через этот объект. Создание объекта-курсора производится с помощью метода cursor(). Для выполнения запроса к базе данных предназначены следующие методы объекта-курсора:
#-*- coding: utf-8 -*- import sqlite3 con = sqlite3.connect("catalog.db") cur = con.cursor() # Создаем объект-курсор sql = """\ CREATE TABLE user ( id_user INTEGER PRIMARY KEY AUTOINCREMENT, email TEXT, passw TEXT ); CREATE TABLE rubr ( id_rubr INTEGER PRIMARY KEY AUTOINCREMENT, name_rubr TEXT ); CREATE TABLE site ( id_site INTEGER PRIMARY KEY AUTOINCREMENT, id_user INTEGER, id_rubr INTEGER, url TEXT, title TEXT, mSg TEXT, iq INTEGER ); """ try: # Обрабатываем исключения cur.executescript(sql) # Выполняем SQL-запросы except sqlite3.DatabaseError as err: print ("Ошибка:", err) else: print("Запрос успешно выполнен") cur.close() # Закрываем объект-курсор con.close() # Закрываем соединение input ()
Сохраняем код в файле, а затем запускаем его с помощью двойного щелчка на значке файла. Обратите внимание на то, что мы работаем с кодировкой UTF-8, которая используется в SQLite по умолчанию;
#-*- coding: utf-8 -*- import sqlite3 con = sqlite3.connect("catalog.db") cur = con.cursor() # Создаем объект-курсор sql = """\ INSERT INTO user (email, passw) VALUES ('unicross@mail.ru', 'password1') """ try: cur.execute(sql) # Выполняем SQL-запрос except sqlite3.DatabaseError as err: print ("Ошибка:", err) else: print("Запрос успешно выполнен") con.commit() # Завершаем транзакцию cur.close() # Закрываем объект-курсор con.close() # Закрываем соединение input ()
В этом примере мы использовали метод commit() объекта соединения. Метод commit() позволяет завершить транзакцию, которая запускается автоматически. Если метод не вызвать и при этом закрыть соединение с базой данных, то все произведенные изменения будут автоматически отменены. Более подробно управление транзакциями мы рассмотрим далее в следующих шагах, а сейчас следует запомнить, что запросы, изменяющие записи (INSERT, REPLACE, UPDATE и DELETE), нужно завершать вызовом метода commit().
В некоторых случаях в SQL-запрос необходимо подставлять данные, полученные от пользователя. Если данные не обработать и подставить в SQL-запрос, то пользователь получает возможность видоизменить запрос и, например, зайти в закрытый раздел без ввода пароля. Чтобы значения были правильно подставлены, нужно их передавать в виде кортежа или словаря во втором параметре метода execute (). В этом случае в SQL-запросе указываются следующие специальные заполнители;
Для примера заполним таблицу с рубриками этими способами:
#-*- coding: utf-8 -*- import sqlite3 con = sqlite3.connect("catalog.db") cur = con.cursor() # Создаем объект-курсор t1 = ("Программирование",) t2 = (2, "Музыка") d = {"id": 3, "name": """Поисковые ' " порталы"""} sql_t1 = "INSERT INTO rubr (name_rubr) VALUES (?)" sql_t2 = "INSERT INTO rubr VALUES (?,?)" sql_d = "INSERT INTO rubr VALUES (:id, :name)" try: cur.execute(sql_t1, t1) # Кортеж из 1-го элемента cur.execute(sql_t2, t2) # Кортеж из 2-х элементов cur.execute(sql_d, d) # Словарь except sqlite3.DatabaseError as err: print ("Ошибка:", err) else: print("Запрос успешно выполнен") con.commit() # Завершаем транзакцию cur.close() # Закрываем объект-курсор con.close() # Закрываем соединение input ()
Обратите внимание на значение переменной t1. Перед закрывающей круглой скобкой запятая указана не по ошибке. Если запятую убрать, то вместо кортежа мы получим строку, - не скобки создают кортеж, а запятые. Поэтому при создании кортежа из одного элемента в конце необходимо добавить запятую. Как показывает практика, новички постоянно забывают указать запятую и при этом получают сообщение об ошибке.
В значении ключа name переменной d апостроф и двойная кавычка также указаны не случайно. Это значение показывает, что при подстановке все специальные символы экранируются, поэтому никакой ошибки при вставке значения в таблицу не будет.
#-*- coding: utf-8 -*- import sqlite3 con = sqlite3.connect("catalog.db") cur = con.cursor() # Создаем объект-курсор arr = [ (1, 1, "http://wwwadmin.ru", "Название", "", 100), (1, 1, "http://python.org", "Python", "", 1000), (1, 3, "http://google.ru", "Гугль", "", 3000) ] sql = """\ INSERT INTO site (id_user, id_rubr, url, title, msg, iq) VALUES (?, ?, ?, ?, ?, ?) """ try: cur.executemany(sql, arr) except sqlite3.DatabaseError as err: print ("Ошибка:", err) else: print("Запрос успешно выполнен") con.commit() # Завершаем транзакцию cur.close() # Закрываем объект-курсор con.close() # Закрываем соединение input ()
На следующем шаге мы закончим изучение этого вопроса.