Python: Работаем с базой данных SQLite
В Питоне уже есть функции для работы с базой данных SQLite.
Общий принцип следующий.
- Импортируем библиотеку sqlite3
- Подключаемся к базе данных через connect() с указанием файла, в которой хранится база данных. Если базы данных нет, она будет создана. Если база существует, то соединимся с ней
- Создаём таблицу с указанием столбцов
- Выполняем запрос, например, вставляем в базу новые данные
- Делаем запрос с заданными условиями
import sqlite3 as sl # соединяемся с базой данных con = sl.connect('cat.db') # создаём таблицу CAT with con: con.execute(""" CREATE TABLE CAT ( id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, name TEXT, age INTEGER ); """) # добавляем данные: имя кота и его возраст query = 'INSERT INTO CAT (id, name, age) values(?, ?, ?)' data = [ (1, 'Барсик', 4), (2, 'Мурзик', 8), (3, 'Рыжик', 6), (4, 'Васька', 11) ] with con: con.executemany(query, data) # делаем выборку по условию with con: data = con.execute("SELECT * FROM CAT WHERE age
Как занести в таблицу базы данных SQLite ключ шифрования?
Нужно создать таблицу, в которой были бы колонки с логином, паролем и ключем шифрования. При создании таблицы таким образом, как приведено на отрывке кода ниже возникает ошибка формата:
sqlite3.OperationalError: near "'rNM3EGbZEK3UFaaSPOPlYdgkriznvWpN_T1RaEtfqBU='": syntax error
Как это можно исправить?
text = b"Text for encrypt" cipher_key = Fernet.generate_key() cipher = Fernet(cipher_key) encrypted_text = cipher.encrypt(text) decrypted_text = cipher.decrypt(encrypted_text) print(cipher_key) print(decrypted_text) conn = sqlite3.connect("users.db") cursor = conn.cursor() valu1 = "aleksei" valu2 = 123456 valu3 = cipher_key cursor.execute("""CREATE TABLE IF NOT EXISTS users_data (Login text, Password int, Cipher_Key text);""") cursor.execute(f"""INSERT INTO users_data (Login, Password, Cipher_Key) VALUES (, , );""")
Защита паролем SqLite DB

Установленный пароль не позволит графическому редактору просматривать ваши данные.
Некоторые редакторы могут расшифровать БД, если вы укажете пароль. Используемый алгоритм RSA.
Если вам нужно изменить пароль, используйте:
conn.ChangePassword("new_password");
Для того, чтобы очистить (reset), или удалить пароль, используйте:
conn.ChangePassword(String.Empty);
Также Вы можете использовать встроенное шифрование поставщика sqlite.net(System.Data.SQLite).
Подробнее см. sqlite.phxsoftware.com
Чтобы зашифровать существующую незашифрованную базу данных или, чтобы изменить пароль зашифрованной базы данных, откройте базу данных и затем используйте функцию ChangePassword() в SQLiteConnection:
// Opens an unencrypted database SQLiteConnection cnn = new SQLiteConnection("Data Source=c:\\test.db3"); cnn.Open(); // Encrypts the database. The connection remains valid and usable afterwards. cnn.ChangePassword("mypassword");
Чтобы расшифровать существующую зашифрованную базу данных, вызов ChangePassword() с паролем NULL или "":
// Opens an encrypted database SQLiteConnection cnn = new SQLiteConnection("Data Source=c:\\test.db3;Password=mypassword"); cnn.Open(); // Removes the encryption on an encrypted database. cnn.ChangePassword(null);
Чтобы открыть существующую зашифрованную базу данных или создать новую зашифрованную базу данных, укажите пароль в ConnectionString, как показано в предыдущем примере, либо вызовите функцию SetPassword() прежде, чем открывать новое соединение SQLiteConnection.
Пароль, указанный в ConnectionString, должен быть пустым (cleartext), но пароли, предоставляемые в функции SetPassword(), могут быть двоичными байтовыми массивами.
// Opens an encrypted database by calling SetPassword() SQLiteConnection cnn = new SQLiteConnection("Data Source=c:\\test.db3"); cnn.SetPassword(new byte[] { 0xFF, 0xEE, 0xDD, 0x10, 0x20, 0x30 >); cnn.Open(); // The connection is now usable
По умолчанию ключевое слово ATTACH будет использовать тот же ключ шифрования, что и основная база данных при присоединении другого файла базы данных к существующему соединению. Чтобы изменить это поведение, вы используете модификатор KEY следующим образом:
Если вы прикрепляете зашифрованную базу данных с помощью пароля открытого текста:
// Attach to a database using a different key than the main database SQLiteConnection cnn = new SQLiteConnection("Data Source=c:\\test.db3"); cnn.Open(); cmd = new SQLiteCommand("ATTACH DATABASE 'c:\\pwd.db3' AS [Protected] KEY 'mypassword'", cnn); cmd.ExecuteNonQuery();
Чтобы подключить зашифрованную базу данных с помощью двоичного пароля:
// Attach to a database encrypted with a binary key SQLiteConnection cnn = new SQLiteConnection("Data Source=c:\\test.db3"); cnn.Open(); cmd = new SQLiteCommand("ATTACH DATABASE 'c:\\pwd.db3' AS [Protected] KEY X'FFEEDD102030'", cnn); cmd.ExecuteNonQuery();
Как зашифровать данные в sqlite python
Рассмотрим основные операции с базой данных SQLite с помощью библиотеки sqlite3 на примере таблицы:
CREATE TABLE people ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, age INTEGER )
Добавление данных
Для добавления данных применяется SQL-инструкция INSERT . Для добавления одной строки используем метод execute() объекта Cursor:
import sqlite3; con = sqlite3.connect("metanit.db") cursor = con.cursor() # добавляем строку в таблицу people cursor.execute("INSERT INTO people (name, age) VALUES ('Tom', 38)") # выполняем транзакцию con.commit()
Здесь добавляется одна строка, где name = "Tom", а age = 38.
Выражение INSERT неявно открывает транзакцию, для завершения которой необходимо вызвать метод commit() текущего объекта Connection.
Установка параметров
С помощью второго параметра в метод execute() можно передать значения для параметров SQL-запроса:
import sqlite3; con = sqlite3.connect("metanit.db") cursor = con.cursor() # данные для добавления bob = ("Bob", 42) cursor.execute("INSERT INTO people (name, age) VALUES (?, ?)", bob) con.commit()
В данном случае добавляемые в БД значения представляют кортеж bob. В SQL-запросе вместо конкретных значений используются знаки подстановки ?. Вместо этих символов при выполнении запроса будут вставляться данные из кортежа data. Так, первый элемент кортежа - строка "Bob" передается на место первого знакак ?, второй элемент - число 42 передается на место второго знака ?.
И если мы посмотрим на содержимое базы данных, то найдем там все добавленные объекты:

Множественная вставка
Метод executemany() позволяет вставить набор строк:
import sqlite3; con = sqlite3.connect("metanit.db") cursor = con.cursor() # данные для добавления people = [("Sam", 28), ("Alice", 33), ("Kate", 25)] cursor.executemany("INSERT INTO people (name, age) VALUES (?, ?)", people) con.commit()
В метод cursor.executemany() по сути передается то же самое выражение SQL, только теперь данные определены в виде списка кортежей people. Фактически каждый кортеж в этом списке представляет отдельную строку - данные отдельного пользователя, и при выполнении метода для каждого кортежа будет создаваться свое выражение INSERT INTO

Получение данных
Для получения данных применяется SQL-команда SELECT . После выполнения этой команды курсор получает данные, которые можно получить с помощью одного из методов: fetchall() (возвращает список со всеми строками), fetchmany() (возвращает указанное количество строк) и fetchone() (возвращает одну в наборе строку).
Получение всех строк
Например, получим все ранее добавленные данные из таблицы people:
import sqlite3; con = sqlite3.connect("metanit.db") cursor = con.cursor() # получаем все данные из таблицы people cursor.execute("SELECT * FROM people") print(cursor.fetchall())
При выполнении этой программы на консоль будет выведен список строк, где каждая строка представляет кортеж:
[(1, 'Tom', 38), (2, 'Bob', 42), (3, 'Sam', 28), (4, 'Alice', 33), (5, 'Kate', 25)]
При необходимости мы можем перебрать список, используя стандартные циклические конструкции:
import sqlite3; con = sqlite3.connect("metanit.db") cursor = con.cursor() cursor.execute("SELECT * FROM people") for person in cursor.fetchall(): print(f" - ")
Результат работы программы:
Tom - 38 Bob - 42 Sam - 28 Alice - 33 Kate - 25
Стоит отметить, что в примере выше необязательно вызывать метод fetchall, мы можем перебрать курсор в цикле как обычный набор:
for person in cursor: print(f" - ")
Получение части строк
Получение части строк с помощью метода fetchmany() , в который передается количество строк:
import sqlite3; con = sqlite3.connect("metanit.db") cursor = con.cursor() cursor.execute("SELECT * FROM people") # извлекаем первые 3 строки в полученном наборе print(cursor.fetchmany(3))
Результат работы программы:
[(1, 'Tom', 38), (2, 'Bob', 42), (3, 'Sam', 28)]
Выполнение этого метода извлекает следующие ранее неизвлеченные строки:
# извлекаем первые 3 строки в полученном наборе print(cursor.fetchmany(3)) # [(1, 'Tom', 38), (2, 'Bob', 42), (3, 'Sam', 28)] # извлекаем следующие 3 строки в полученном наборе print(cursor.fetchmany(3)) # [(4, 'Alice', 33), (5, 'Kate', 25)]
Получение одной строки
Метод fetchone() извлекает следующую строку в виде кортежа значений и возвращает его. Если строк больше нет, то возвращает None :
import sqlite3; con = sqlite3.connect("metanit.db") cursor = con.cursor() cursor.execute("SELECT * FROM people") # извлекаем одну строку print(cursor.fetchone()) # (1, 'Tom', 38)
Данный метод удобно применять, когда нам надо извлечь из базы данных только один объект:
import sqlite3; con = sqlite3.connect("metanit.db") cursor = con.cursor() cursor.execute("SELECT name, age FROM people WHERE раскладываем кортеж на две переменных name, age = cursor.fetchone() print(f"Name: Age: ") # Name: Bob Age: 42
Здесь получаем из бд строку с и полученный результат раскладываем на две переменных name и age (так как кортеж в Python можно разложить на отдельные значения)
Обновление
Для обновления в SQL выполняется команда UPDATE . Например, заменим у всех пользователей имя с Tom на Tomas:
import sqlite3; con = sqlite3.connect("metanit.db") cursor = con.cursor() # обновляем строки, где name = Tom cursor.execute("UPDATE people SET name ='Tomas' WHERE name='Tom'") # вариант с подстановками # cursor.execute("UPDATE people SET name =? WHERE name=?", ("Tomas", "Tom")) con.commit() # проверяем cursor.execute("SELECT * FROM people") print(cursor.fetchall()) # [(1, 'Tomas', 38), (2, 'Bob', 42), (3, 'Sam', 28), (4, 'Alice', 33), (5, 'Kate', 25)]
Для выполнения обновления также надо выполнять метод con.commit()
Удаление данных
Для удаления в SQL выполняется команда DЕLETE . Например, удалим всех пользователей с именем Bob:
import sqlite3; con = sqlite3.connect("metanit.db") cursor = con.cursor() # обновляем строки, где name = Tom cursor.execute("DELETE FROM people WHERE name=?", ("Bob",)) con.commit() # проверяем cursor.execute("SELECT * FROM people") print(cursor.fetchall()) # [(1, 'Tomas', 38), (3, 'Sam', 28), (4, 'Alice', 33), (5, 'Kate', 25)]
Для выполнения удаления также надо выполнять метод con.commit()